|
@@ -3,7 +3,7 @@
|
|
* For more information, see LICENCE in the main folder
|
|
* For more information, see LICENCE in the main folder
|
|
*
|
|
*
|
|
* This file is separated in five sections:
|
|
* This file is separated in five sections:
|
|
- * (1) Private typedefs, enums, structures, defines and gblobal variables
|
|
|
|
|
|
+ * (1) Private typedefs, enums, structures, defines and global variables
|
|
* (2) Private functions
|
|
* (2) Private functions
|
|
* (3) Protected functions used internally
|
|
* (3) Protected functions used internally
|
|
* (4) Protected functions used in the interface of the database
|
|
* (4) Protected functions used in the interface of the database
|
|
@@ -47,6 +47,7 @@
|
|
* - create a db that organizes itself by splaying
|
|
* - create a db that organizes itself by splaying
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* HISTORY:
|
|
|
|
+ * 2013/08/25 - Added int64/uint64 support for keys [Ind/Hercules]
|
|
* 2012/03/09 - Added enum for data types (int, uint, void*)
|
|
* 2012/03/09 - Added enum for data types (int, uint, void*)
|
|
* 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly.
|
|
* 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly.
|
|
* 2007/11/09 - Added an iterator to the database.
|
|
* 2007/11/09 - Added an iterator to the database.
|
|
@@ -82,15 +83,15 @@
|
|
* DBNColor - Enumeration of colors of the nodes. *
|
|
* DBNColor - Enumeration of colors of the nodes. *
|
|
* DBNode - Structure of a node in RED-BLACK trees. *
|
|
* DBNode - Structure of a node in RED-BLACK trees. *
|
|
* struct db_free - Structure that holds a deleted node to be freed. *
|
|
* struct db_free - Structure that holds a deleted node to be freed. *
|
|
- * DBMap_impl - Struture of the database. *
|
|
|
|
|
|
+ * DBMap_impl - Structure of the database. *
|
|
* stats - Statistics about the database system. *
|
|
* stats - Statistics about the database system. *
|
|
\*****************************************************************************/
|
|
\*****************************************************************************/
|
|
|
|
|
|
/**
|
|
/**
|
|
- * If defined statistics about database nodes, database creating/destruction
|
|
|
|
- * and function usage are keept and displayed when finalizing the database
|
|
|
|
|
|
+ * If defined statistics about database nodes, database creating/destruction
|
|
|
|
+ * and function usage are kept and displayed when finalizing the database
|
|
* system.
|
|
* system.
|
|
- * WARNING: This adds overhead to every database operation (not shure how much).
|
|
|
|
|
|
+ * WARNING: This adds overhead to every database operation (not sure how much).
|
|
* @private
|
|
* @private
|
|
* @see #DBStats
|
|
* @see #DBStats
|
|
* @see #stats
|
|
* @see #stats
|
|
@@ -234,10 +235,14 @@ static struct db_stats {
|
|
uint32 db_uint_alloc;
|
|
uint32 db_uint_alloc;
|
|
uint32 db_string_alloc;
|
|
uint32 db_string_alloc;
|
|
uint32 db_istring_alloc;
|
|
uint32 db_istring_alloc;
|
|
|
|
+ uint32 db_int64_alloc;
|
|
|
|
+ uint32 db_uint64_alloc;
|
|
uint32 db_int_destroy;
|
|
uint32 db_int_destroy;
|
|
uint32 db_uint_destroy;
|
|
uint32 db_uint_destroy;
|
|
uint32 db_string_destroy;
|
|
uint32 db_string_destroy;
|
|
uint32 db_istring_destroy;
|
|
uint32 db_istring_destroy;
|
|
|
|
+ uint32 db_int64_destroy;
|
|
|
|
+ uint32 db_uint64_destroy;
|
|
// Function usage counters
|
|
// Function usage counters
|
|
uint32 db_rotate_left;
|
|
uint32 db_rotate_left;
|
|
uint32 db_rotate_right;
|
|
uint32 db_rotate_right;
|
|
@@ -254,10 +259,14 @@ static struct db_stats {
|
|
uint32 db_uint_cmp;
|
|
uint32 db_uint_cmp;
|
|
uint32 db_string_cmp;
|
|
uint32 db_string_cmp;
|
|
uint32 db_istring_cmp;
|
|
uint32 db_istring_cmp;
|
|
|
|
+ uint32 db_int64_cmp;
|
|
|
|
+ uint32 db_uint64_cmp;
|
|
uint32 db_int_hash;
|
|
uint32 db_int_hash;
|
|
uint32 db_uint_hash;
|
|
uint32 db_uint_hash;
|
|
uint32 db_string_hash;
|
|
uint32 db_string_hash;
|
|
uint32 db_istring_hash;
|
|
uint32 db_istring_hash;
|
|
|
|
+ uint32 db_int64_hash;
|
|
|
|
+ uint32 db_uint64_hash;
|
|
uint32 db_release_nothing;
|
|
uint32 db_release_nothing;
|
|
uint32 db_release_key;
|
|
uint32 db_release_key;
|
|
uint32 db_release_data;
|
|
uint32 db_release_data;
|
|
@@ -296,6 +305,8 @@ static struct db_stats {
|
|
uint32 db_i2key;
|
|
uint32 db_i2key;
|
|
uint32 db_ui2key;
|
|
uint32 db_ui2key;
|
|
uint32 db_str2key;
|
|
uint32 db_str2key;
|
|
|
|
+ uint32 db_i642key;
|
|
|
|
+ uint32 db_ui642key;
|
|
uint32 db_i2data;
|
|
uint32 db_i2data;
|
|
uint32 db_ui2data;
|
|
uint32 db_ui2data;
|
|
uint32 db_ptr2data;
|
|
uint32 db_ptr2data;
|
|
@@ -489,7 +500,7 @@ static void db_rebalance_erase(DBNode node, DBNode *root)
|
|
}
|
|
}
|
|
|
|
|
|
// Remove the node from the tree
|
|
// Remove the node from the tree
|
|
- if (y != node) { // both childs existed
|
|
|
|
|
|
+ if (y != node) { // both child existed
|
|
// put the left of 'node' in the left of 'y'
|
|
// put the left of 'node' in the left of 'y'
|
|
node->left->parent = y;
|
|
node->left->parent = y;
|
|
y->left = node->left;
|
|
y->left = node->left;
|
|
@@ -500,10 +511,10 @@ static void db_rebalance_erase(DBNode node, DBNode *root)
|
|
x_parent = y->parent;
|
|
x_parent = y->parent;
|
|
if (x) x->parent = y->parent;
|
|
if (x) x->parent = y->parent;
|
|
y->parent->left = x;
|
|
y->parent->left = x;
|
|
- // put the right of 'node' in 'y'
|
|
|
|
|
|
+ // put the right of 'node' in 'y'
|
|
y->right = node->right;
|
|
y->right = node->right;
|
|
node->right->parent = y;
|
|
node->right->parent = y;
|
|
- // 'y' is a direct child of 'node'
|
|
|
|
|
|
+ // 'y' is a direct child of 'node'
|
|
} else {
|
|
} else {
|
|
x_parent = y;
|
|
x_parent = y;
|
|
}
|
|
}
|
|
@@ -556,7 +567,7 @@ static void db_rebalance_erase(DBNode node, DBNode *root)
|
|
x = x_parent;
|
|
x = x_parent;
|
|
x_parent = x_parent->parent;
|
|
x_parent = x_parent->parent;
|
|
} else {
|
|
} else {
|
|
- if (w->right == NULL || w->right->color == BLACK) {
|
|
|
|
|
|
+ if (w->right == NULL || w->right->color == BLACK) {
|
|
if (w->left) w->left->color = BLACK;
|
|
if (w->left) w->left->color = BLACK;
|
|
w->color = RED;
|
|
w->color = RED;
|
|
db_rotate_right(w, root);
|
|
db_rotate_right(w, root);
|
|
@@ -824,10 +835,14 @@ static void db_free_unlock(DBMap_impl* db)
|
|
* db_uint_cmp - Default comparator for DB_UINT databases. *
|
|
* db_uint_cmp - Default comparator for DB_UINT databases. *
|
|
* db_string_cmp - Default comparator for DB_STRING databases. *
|
|
* db_string_cmp - Default comparator for DB_STRING databases. *
|
|
* db_istring_cmp - Default comparator for DB_ISTRING databases. *
|
|
* db_istring_cmp - Default comparator for DB_ISTRING databases. *
|
|
|
|
+ * db_int64_cmp - Default comparator for DB_INT64 databases. *
|
|
|
|
+ * db_uint64_cmp - Default comparator for DB_UINT64 databases. *
|
|
* db_int_hash - Default hasher for DB_INT databases. *
|
|
* db_int_hash - Default hasher for DB_INT databases. *
|
|
* db_uint_hash - Default hasher for DB_UINT databases. *
|
|
* db_uint_hash - Default hasher for DB_UINT databases. *
|
|
* db_string_hash - Default hasher for DB_STRING databases. *
|
|
* db_string_hash - Default hasher for DB_STRING databases. *
|
|
* db_istring_hash - Default hasher for DB_ISTRING databases. *
|
|
* db_istring_hash - Default hasher for DB_ISTRING databases. *
|
|
|
|
+ * db_int64_hash - Default hasher for DB_INT64 databases. *
|
|
|
|
+ * db_uint64_hash - Default hasher for DB_UINT64 databases. *
|
|
* db_release_nothing - Releaser that releases nothing. *
|
|
* db_release_nothing - Releaser that releases nothing. *
|
|
* db_release_key - Releaser that only releases the key. *
|
|
* db_release_key - Releaser that only releases the key. *
|
|
* db_release_data - Releaser that only releases the data. *
|
|
* db_release_data - Releaser that only releases the data. *
|
|
@@ -914,6 +929,51 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
|
|
return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
|
|
return strncasecmp((const char *)key1.str, (const char *)key2.str, maxlen);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Default comparator for DB_INT64 databases.
|
|
|
|
+ * Compares key1 to key2.
|
|
|
|
+ * Return 0 if equal, negative if lower and positive if higher.
|
|
|
|
+ * <code>maxlen</code> is ignored.
|
|
|
|
+ * @param key1 Key to be compared
|
|
|
|
+ * @param key2 Key being compared to
|
|
|
|
+ * @param maxlen Maximum length of the key to hash
|
|
|
|
+ * @return 0 if equal, negative if lower and positive if higher
|
|
|
|
+ * @see DBType#DB_INT64
|
|
|
|
+ * @see #DBComparator
|
|
|
|
+ * @see #db_default_cmp(DBType)
|
|
|
|
+ */
|
|
|
|
+static int db_int64_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
|
|
|
|
+{
|
|
|
|
+ (void)maxlen;//not used
|
|
|
|
+ DB_COUNTSTAT(db_int64_cmp);
|
|
|
|
+ if (key1.i64 < key2.i64) return -1;
|
|
|
|
+ if (key1.i64 > key2.i64) return 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Default comparator for DB_UINT64 databases.
|
|
|
|
+ * Compares key1 to key2.
|
|
|
|
+ * Return 0 if equal, negative if lower and positive if higher.
|
|
|
|
+ * <code>maxlen</code> is ignored.
|
|
|
|
+ * @param key1 Key to be compared
|
|
|
|
+ * @param key2 Key being compared to
|
|
|
|
+ * @param maxlen Maximum length of the key to hash
|
|
|
|
+ * @return 0 if equal, negative if lower and positive if higher
|
|
|
|
+ * @see DBType#DB_UINT64
|
|
|
|
+ * @see #DBComparator
|
|
|
|
+ * @see #db_default_cmp(DBType)
|
|
|
|
+ */
|
|
|
|
+static int db_uint64_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
|
|
|
|
+{
|
|
|
|
+ (void)maxlen;//not used
|
|
|
|
+ DB_COUNTSTAT(db_uint64_cmp);
|
|
|
|
+ if (key1.ui64 < key2.ui64) return -1;
|
|
|
|
+ if (key1.ui64 > key2.ui64) return 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Default hasher for DB_INT databases.
|
|
* Default hasher for DB_INT databases.
|
|
* Returns the value of the key as an unsigned int.
|
|
* Returns the value of the key as an unsigned int.
|
|
@@ -925,11 +985,11 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen)
|
|
* @see #DBHasher
|
|
* @see #DBHasher
|
|
* @see #db_default_hash(DBType)
|
|
* @see #db_default_hash(DBType)
|
|
*/
|
|
*/
|
|
-static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
|
|
|
|
|
|
+static uint64 db_int_hash(DBKey key, unsigned short maxlen)
|
|
{
|
|
{
|
|
(void)maxlen;//not used
|
|
(void)maxlen;//not used
|
|
DB_COUNTSTAT(db_int_hash);
|
|
DB_COUNTSTAT(db_int_hash);
|
|
- return (unsigned int)key.i;
|
|
|
|
|
|
+ return (uint64)key.i;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -943,11 +1003,11 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen)
|
|
* @see #DBHasher
|
|
* @see #DBHasher
|
|
* @see #db_default_hash(DBType)
|
|
* @see #db_default_hash(DBType)
|
|
*/
|
|
*/
|
|
-static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
|
|
|
|
|
|
+static uint64 db_uint_hash(DBKey key, unsigned short maxlen)
|
|
{
|
|
{
|
|
(void)maxlen;//not used
|
|
(void)maxlen;//not used
|
|
DB_COUNTSTAT(db_uint_hash);
|
|
DB_COUNTSTAT(db_uint_hash);
|
|
- return key.ui;
|
|
|
|
|
|
+ return (uint64)key.ui;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -959,7 +1019,7 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen)
|
|
* @see #DBHasher
|
|
* @see #DBHasher
|
|
* @see #db_default_hash(DBType)
|
|
* @see #db_default_hash(DBType)
|
|
*/
|
|
*/
|
|
-static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
|
|
|
|
|
|
+static uint64 db_string_hash(DBKey key, unsigned short maxlen)
|
|
{
|
|
{
|
|
const char *k = key.str;
|
|
const char *k = key.str;
|
|
unsigned int hash = 0;
|
|
unsigned int hash = 0;
|
|
@@ -974,7 +1034,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- return hash;
|
|
|
|
|
|
+ return (uint64)hash;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -985,7 +1045,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen)
|
|
* @see DBType#DB_ISTRING
|
|
* @see DBType#DB_ISTRING
|
|
* @see #db_default_hash(DBType)
|
|
* @see #db_default_hash(DBType)
|
|
*/
|
|
*/
|
|
-static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
|
|
|
|
|
|
+static uint64 db_istring_hash(DBKey key, unsigned short maxlen)
|
|
{
|
|
{
|
|
const char *k = key.str;
|
|
const char *k = key.str;
|
|
unsigned int hash = 0;
|
|
unsigned int hash = 0;
|
|
@@ -1000,7 +1060,43 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- return hash;
|
|
|
|
|
|
+ return (uint64)hash;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Default hasher for DB_INT64 databases.
|
|
|
|
+ * Returns the value of the key as an unsigned int.
|
|
|
|
+ * <code>maxlen</code> is ignored.
|
|
|
|
+ * @param key Key to be hashed
|
|
|
|
+ * @param maxlen Maximum length of the key to hash
|
|
|
|
+ * @return hash of the key
|
|
|
|
+ * @see DBType#DB_INT64
|
|
|
|
+ * @see #DBHasher
|
|
|
|
+ * @see #db_default_hash(DBType)
|
|
|
|
+ */
|
|
|
|
+static uint64 db_int64_hash(DBKey key, unsigned short maxlen)
|
|
|
|
+{
|
|
|
|
+ (void)maxlen;//not used
|
|
|
|
+ DB_COUNTSTAT(db_int64_hash);
|
|
|
|
+ return (uint64)key.i64;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Default hasher for DB_UINT64 databases.
|
|
|
|
+ * Just returns the value of the key.
|
|
|
|
+ * <code>maxlen</code> is ignored.
|
|
|
|
+ * @param key Key to be hashed
|
|
|
|
+ * @param maxlen Maximum length of the key to hash
|
|
|
|
+ * @return hash of the key
|
|
|
|
+ * @see DBType#DB_UINT64
|
|
|
|
+ * @see #DBHasher
|
|
|
|
+ * @see #db_default_hash(DBType)
|
|
|
|
+ */
|
|
|
|
+static uint64 db_uint64_hash(DBKey key, unsigned short maxlen)
|
|
|
|
+{
|
|
|
|
+ (void)maxlen;//not used
|
|
|
|
+ DB_COUNTSTAT(db_uint64_hash);
|
|
|
|
+ return key.ui64;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1117,7 +1213,7 @@ static void db_release_both(DBKey key, DBData data, DBRelease which)
|
|
DBData* dbit_obj_first(DBIterator* self, DBKey* out_key)
|
|
DBData* dbit_obj_first(DBIterator* self, DBKey* out_key)
|
|
{
|
|
{
|
|
DBIterator_impl* it = (DBIterator_impl*)self;
|
|
DBIterator_impl* it = (DBIterator_impl*)self;
|
|
-
|
|
|
|
|
|
+
|
|
DB_COUNTSTAT(dbit_first);
|
|
DB_COUNTSTAT(dbit_first);
|
|
// position before the first entry
|
|
// position before the first entry
|
|
it->ht_index = -1;
|
|
it->ht_index = -1;
|
|
@@ -1139,7 +1235,7 @@ DBData* dbit_obj_first(DBIterator* self, DBKey* out_key)
|
|
DBData* dbit_obj_last(DBIterator* self, DBKey* out_key)
|
|
DBData* dbit_obj_last(DBIterator* self, DBKey* out_key)
|
|
{
|
|
{
|
|
DBIterator_impl* it = (DBIterator_impl*)self;
|
|
DBIterator_impl* it = (DBIterator_impl*)self;
|
|
-
|
|
|
|
|
|
+
|
|
DB_COUNTSTAT(dbit_last);
|
|
DB_COUNTSTAT(dbit_last);
|
|
// position after the last entry
|
|
// position after the last entry
|
|
it->ht_index = HASH_SIZE;
|
|
it->ht_index = HASH_SIZE;
|
|
@@ -1261,7 +1357,6 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key)
|
|
node = &fake;
|
|
node = &fake;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
while( node )
|
|
while( node )
|
|
{// next node
|
|
{// next node
|
|
if( node->left )
|
|
if( node->left )
|
|
@@ -1303,7 +1398,7 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key)
|
|
|
|
|
|
/**
|
|
/**
|
|
* Returns true if the fetched entry exists.
|
|
* Returns true if the fetched entry exists.
|
|
- * The databases entries might have NULL data, so use this to to test if
|
|
|
|
|
|
+ * The databases entries might have NULL data, so use this to to test if
|
|
* the iterator is done.
|
|
* the iterator is done.
|
|
* @param self Iterator
|
|
* @param self Iterator
|
|
* @return true if the entry exists
|
|
* @return true if the entry exists
|
|
@@ -1320,7 +1415,7 @@ bool dbit_obj_exists(DBIterator* self)
|
|
|
|
|
|
/**
|
|
/**
|
|
* Removes the current entry from the database.
|
|
* Removes the current entry from the database.
|
|
- * NOTE: {@link DBIterator#exists} will return false until another entry
|
|
|
|
|
|
+ * NOTE: {@link DBIterator#exists} will return false until another entry
|
|
* is fetched
|
|
* is fetched
|
|
* Puts data of the removed entry in out_data, if out_data is not NULL.
|
|
* Puts data of the removed entry in out_data, if out_data is not NULL.
|
|
* @param self Iterator
|
|
* @param self Iterator
|
|
@@ -1371,7 +1466,7 @@ void dbit_obj_destroy(DBIterator* self)
|
|
/**
|
|
/**
|
|
* Returns a new iterator for this database.
|
|
* Returns a new iterator for this database.
|
|
* The iterator keeps the database locked until it is destroyed.
|
|
* The iterator keeps the database locked until it is destroyed.
|
|
- * The database will keep functioning normally but will only free internal
|
|
|
|
|
|
+ * The database will keep functioning normally but will only free internal
|
|
* memory when unlocked, so destroy the iterator as soon as possible.
|
|
* memory when unlocked, so destroy the iterator as soon as possible.
|
|
* @param self Database
|
|
* @param self Database
|
|
* @return New iterator
|
|
* @return New iterator
|
|
@@ -1507,7 +1602,7 @@ static DBData* db_obj_get(DBMap* self, DBKey key)
|
|
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
|
|
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
|
|
* If <code>buf</code> is NULL, it only counts the matches.
|
|
* If <code>buf</code> is NULL, it only counts the matches.
|
|
* Returns the number of entries that matched.
|
|
* Returns the number of entries that matched.
|
|
- * NOTE: if the value returned is greater than <code>max</code>, only the
|
|
|
|
|
|
+ * NOTE: if the value returned is greater than <code>max</code>, only the
|
|
* first <code>max</code> entries found are put into the buffer.
|
|
* first <code>max</code> entries found are put into the buffer.
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param buf Buffer to put the data of the matched entries
|
|
* @param buf Buffer to put the data of the matched entries
|
|
@@ -1546,17 +1641,17 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max,
|
|
}
|
|
}
|
|
va_end(argscopy);
|
|
va_end(argscopy);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (node->left) {
|
|
if (node->left) {
|
|
node = node->left;
|
|
node = node->left;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (node->right) {
|
|
if (node->right) {
|
|
node = node->right;
|
|
node = node->right;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
while (node) {
|
|
while (node) {
|
|
parent = node->parent;
|
|
parent = node->parent;
|
|
if (parent && parent->right && parent->left == node) {
|
|
if (parent && parent->right && parent->left == node) {
|
|
@@ -1578,7 +1673,7 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max,
|
|
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
|
|
* It puts a maximum of <code>max</code> entries into <code>buf</code>.
|
|
* If <code>buf</code> is NULL, it only counts the matches.
|
|
* If <code>buf</code> is NULL, it only counts the matches.
|
|
* Returns the number of entries that matched.
|
|
* Returns the number of entries that matched.
|
|
- * NOTE: if the value returned is greater than <code>max</code>, only the
|
|
|
|
|
|
+ * NOTE: if the value returned is greater than <code>max</code>, only the
|
|
* first <code>max</code> entries found are put into the buffer.
|
|
* first <code>max</code> entries found are put into the buffer.
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param buf Buffer to put the data of the matched entries
|
|
* @param buf Buffer to put the data of the matched entries
|
|
@@ -1606,7 +1701,7 @@ static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, D
|
|
|
|
|
|
/**
|
|
/**
|
|
* Get the data of the entry identified by the key.
|
|
* Get the data of the entry identified by the key.
|
|
- * If the entry does not exist, an entry is added with the data returned by
|
|
|
|
|
|
+ * If the entry does not exist, an entry is added with the data returned by
|
|
* <code>create</code>.
|
|
* <code>create</code>.
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param key Key that identifies the entry
|
|
* @param key Key that identifies the entry
|
|
@@ -1705,7 +1800,7 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li
|
|
/**
|
|
/**
|
|
* Just calls {@link DBMap#vensure}.
|
|
* Just calls {@link DBMap#vensure}.
|
|
* Get the data of the entry identified by the key.
|
|
* Get the data of the entry identified by the key.
|
|
- * If the entry does not exist, an entry is added with the data returned by
|
|
|
|
|
|
+ * If the entry does not exist, an entry is added with the data returned by
|
|
* <code>create</code>.
|
|
* <code>create</code>.
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param key Key that identifies the entry
|
|
* @param key Key that identifies the entry
|
|
@@ -1863,7 +1958,7 @@ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data)
|
|
db->alloc_file, db->alloc_line);
|
|
db->alloc_file, db->alloc_line);
|
|
return 0; // nullpo candidate
|
|
return 0; // nullpo candidate
|
|
}
|
|
}
|
|
- if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
|
|
|
|
|
|
+ if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) {
|
|
ShowError("db_remove: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
|
|
ShowError("db_remove: Attempted to use non-allowed NULL key for db allocated at %s:%d\n",db->alloc_file, db->alloc_line);
|
|
return 0; // nullpo candidate
|
|
return 0; // nullpo candidate
|
|
}
|
|
}
|
|
@@ -1956,7 +2051,7 @@ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args)
|
|
* Apply <code>func</code> to every entry in the database.
|
|
* Apply <code>func</code> to every entry in the database.
|
|
* Returns the sum of values returned by func.
|
|
* Returns the sum of values returned by func.
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
- * @param func Function to be applyed
|
|
|
|
|
|
+ * @param func Function to be applied
|
|
* @param ... Extra arguments for func
|
|
* @param ... Extra arguments for func
|
|
* @return Sum of the values returned by func
|
|
* @return Sum of the values returned by func
|
|
* @protected
|
|
* @protected
|
|
@@ -2053,7 +2148,7 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args)
|
|
* Before deleting an entry, func is applied to it.
|
|
* Before deleting an entry, func is applied to it.
|
|
* Releases the key and the data.
|
|
* Releases the key and the data.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
- * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
|
|
|
|
+ * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
* a database entry will give an error and be aborted (except for clearing).
|
|
* a database entry will give an error and be aborted (except for clearing).
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param func Function to be applied to every entry before deleting
|
|
* @param func Function to be applied to every entry before deleting
|
|
@@ -2081,7 +2176,7 @@ static int db_obj_clear(DBMap* self, DBApply func, ...)
|
|
* Finalize the database, feeing all the memory it uses.
|
|
* Finalize the database, feeing all the memory it uses.
|
|
* Before deleting an entry, func is applied to it.
|
|
* Before deleting an entry, func is applied to it.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
- * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
|
|
|
|
+ * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
* a database entry will give an error and be aborted (except for clearing).
|
|
* a database entry will give an error and be aborted (except for clearing).
|
|
* @param self Interface of the database
|
|
* @param self Interface of the database
|
|
* @param func Function to be applied to every entry before deleting
|
|
* @param func Function to be applied to every entry before deleting
|
|
@@ -2114,6 +2209,8 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args)
|
|
case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break;
|
|
case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break;
|
|
case DB_STRING: DB_COUNTSTAT(db_string_destroy); break;
|
|
case DB_STRING: DB_COUNTSTAT(db_string_destroy); break;
|
|
case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break;
|
|
case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break;
|
|
|
|
+ case DB_INT64: DB_COUNTSTAT(db_int64_destroy); break;
|
|
|
|
+ case DB_UINT64: DB_COUNTSTAT(db_uint64_destroy); break;
|
|
}
|
|
}
|
|
#endif /* DB_ENABLE_STATS */
|
|
#endif /* DB_ENABLE_STATS */
|
|
db_free_lock(db);
|
|
db_free_lock(db);
|
|
@@ -2134,7 +2231,7 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args)
|
|
* Before deleting an entry, func is applied to it.
|
|
* Before deleting an entry, func is applied to it.
|
|
* Releases the key and the data.
|
|
* Releases the key and the data.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
* Returns the sum of values returned by func, if it exists.
|
|
- * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
|
|
|
|
+ * NOTE: This locks the database globally. Any attempt to insert or remove
|
|
* a database entry will give an error and be aborted.
|
|
* a database entry will give an error and be aborted.
|
|
* @param self Database
|
|
* @param self Database
|
|
* @param func Function to be applied to every entry before deleting
|
|
* @param func Function to be applied to every entry before deleting
|
|
@@ -2233,11 +2330,13 @@ static DBOptions db_obj_options(DBMap* self)
|
|
* db_default_cmp - Get the default comparator for a type of database.
|
|
* db_default_cmp - Get the default comparator for a type of database.
|
|
* db_default_hash - Get the default hasher for a type of database.
|
|
* db_default_hash - Get the default hasher for a type of database.
|
|
* db_default_release - Get the default releaser for a type of database with the specified options.
|
|
* db_default_release - Get the default releaser for a type of database with the specified options.
|
|
- * db_custom_release - Get a releaser that behaves a certains way.
|
|
|
|
|
|
+ * db_custom_release - Get a releaser that behaves a certain way.
|
|
* db_alloc - Allocate a new database.
|
|
* db_alloc - Allocate a new database.
|
|
* db_i2key - Manual cast from 'int' to 'DBKey'.
|
|
* db_i2key - Manual cast from 'int' to 'DBKey'.
|
|
* db_ui2key - Manual cast from 'unsigned int' to 'DBKey'.
|
|
* db_ui2key - Manual cast from 'unsigned int' to 'DBKey'.
|
|
* db_str2key - Manual cast from 'unsigned char *' to 'DBKey'.
|
|
* db_str2key - Manual cast from 'unsigned char *' to 'DBKey'.
|
|
|
|
+ * db_i642key - Manual cast from 'int64' to 'DBKey'.
|
|
|
|
+ * db_ui642key - Manual cast from 'uin64' to 'DBKey'.
|
|
* db_i2data - Manual cast from 'int' to 'DBData'.
|
|
* db_i2data - Manual cast from 'int' to 'DBData'.
|
|
* db_ui2data - Manual cast from 'unsigned int' to 'DBData'.
|
|
* db_ui2data - Manual cast from 'unsigned int' to 'DBData'.
|
|
* db_ptr2data - Manual cast from 'void*' to 'DBData'.
|
|
* db_ptr2data - Manual cast from 'void*' to 'DBData'.
|
|
@@ -2264,7 +2363,9 @@ DBOptions db_fix_options(DBType type, DBOptions options)
|
|
DB_COUNTSTAT(db_fix_options);
|
|
DB_COUNTSTAT(db_fix_options);
|
|
switch (type) {
|
|
switch (type) {
|
|
case DB_INT:
|
|
case DB_INT:
|
|
- case DB_UINT: // Numeric database, do nothing with the keys
|
|
|
|
|
|
+ case DB_UINT:
|
|
|
|
+ case DB_INT64:
|
|
|
|
+ case DB_UINT64: // Numeric database, do nothing with the keys
|
|
return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY));
|
|
return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY));
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -2284,6 +2385,8 @@ DBOptions db_fix_options(DBType type, DBOptions options)
|
|
* @see #db_uint_cmp(DBKey,DBKey,unsigned short)
|
|
* @see #db_uint_cmp(DBKey,DBKey,unsigned short)
|
|
* @see #db_string_cmp(DBKey,DBKey,unsigned short)
|
|
* @see #db_string_cmp(DBKey,DBKey,unsigned short)
|
|
* @see #db_istring_cmp(DBKey,DBKey,unsigned short)
|
|
* @see #db_istring_cmp(DBKey,DBKey,unsigned short)
|
|
|
|
+ * @see #db_int64_cmp(DBKey,DBKey,unsigned short)
|
|
|
|
+ * @see #db_uint64_cmp(DBKey,DBKey,unsigned short)
|
|
*/
|
|
*/
|
|
DBComparator db_default_cmp(DBType type)
|
|
DBComparator db_default_cmp(DBType type)
|
|
{
|
|
{
|
|
@@ -2293,6 +2396,8 @@ DBComparator db_default_cmp(DBType type)
|
|
case DB_UINT: return &db_uint_cmp;
|
|
case DB_UINT: return &db_uint_cmp;
|
|
case DB_STRING: return &db_string_cmp;
|
|
case DB_STRING: return &db_string_cmp;
|
|
case DB_ISTRING: return &db_istring_cmp;
|
|
case DB_ISTRING: return &db_istring_cmp;
|
|
|
|
+ case DB_INT64: return &db_int64_cmp;
|
|
|
|
+ case DB_UINT64: return &db_uint64_cmp;
|
|
default:
|
|
default:
|
|
ShowError("db_default_cmp: Unknown database type %u\n", type);
|
|
ShowError("db_default_cmp: Unknown database type %u\n", type);
|
|
return NULL;
|
|
return NULL;
|
|
@@ -2308,6 +2413,8 @@ DBComparator db_default_cmp(DBType type)
|
|
* @see #db_uint_hash(DBKey,unsigned short)
|
|
* @see #db_uint_hash(DBKey,unsigned short)
|
|
* @see #db_string_hash(DBKey,unsigned short)
|
|
* @see #db_string_hash(DBKey,unsigned short)
|
|
* @see #db_istring_hash(DBKey,unsigned short)
|
|
* @see #db_istring_hash(DBKey,unsigned short)
|
|
|
|
+ * @see #db_int64_hash(DBKey,unsigned short)
|
|
|
|
+ * @see #db_uint64_hash(DBKey,unsigned short)
|
|
*/
|
|
*/
|
|
DBHasher db_default_hash(DBType type)
|
|
DBHasher db_default_hash(DBType type)
|
|
{
|
|
{
|
|
@@ -2317,6 +2424,8 @@ DBHasher db_default_hash(DBType type)
|
|
case DB_UINT: return &db_uint_hash;
|
|
case DB_UINT: return &db_uint_hash;
|
|
case DB_STRING: return &db_string_hash;
|
|
case DB_STRING: return &db_string_hash;
|
|
case DB_ISTRING: return &db_istring_hash;
|
|
case DB_ISTRING: return &db_istring_hash;
|
|
|
|
+ case DB_INT64: return &db_int64_hash;
|
|
|
|
+ case DB_UINT64: return &db_uint64_hash;
|
|
default:
|
|
default:
|
|
ShowError("db_default_hash: Unknown database type %u\n", type);
|
|
ShowError("db_default_hash: Unknown database type %u\n", type);
|
|
return NULL;
|
|
return NULL;
|
|
@@ -2324,7 +2433,7 @@ DBHasher db_default_hash(DBType type)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Returns the default releaser for the specified type of database with the
|
|
|
|
|
|
+ * Returns the default releaser for the specified type of database with the
|
|
* specified options.
|
|
* specified options.
|
|
* NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)}
|
|
* NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)}
|
|
* before choosing the releaser.
|
|
* before choosing the releaser.
|
|
@@ -2385,7 +2494,7 @@ DBReleaser db_custom_release(DBRelease which)
|
|
* @param line Line of the file where the database is being allocated
|
|
* @param line Line of the file where the database is being allocated
|
|
* @param type Type of database
|
|
* @param type Type of database
|
|
* @param options Options of the database
|
|
* @param options Options of the database
|
|
- * @param maxlen Maximum length of the string to be used as key in string
|
|
|
|
|
|
+ * @param maxlen Maximum length of the string to be used as key in string
|
|
* databases. If 0, the maximum number of maxlen is used (64K).
|
|
* databases. If 0, the maximum number of maxlen is used (64K).
|
|
* @return The interface of the database
|
|
* @return The interface of the database
|
|
* @public
|
|
* @public
|
|
@@ -2404,6 +2513,8 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi
|
|
case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break;
|
|
case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break;
|
|
case DB_STRING: DB_COUNTSTAT(db_string_alloc); break;
|
|
case DB_STRING: DB_COUNTSTAT(db_string_alloc); break;
|
|
case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break;
|
|
case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break;
|
|
|
|
+ case DB_INT64: DB_COUNTSTAT(db_int64_alloc); break;
|
|
|
|
+ case DB_UINT64: DB_COUNTSTAT(db_uint64_alloc); break;
|
|
}
|
|
}
|
|
#endif /* DB_ENABLE_STATS */
|
|
#endif /* DB_ENABLE_STATS */
|
|
CREATE(db, struct DBMap_impl, 1);
|
|
CREATE(db, struct DBMap_impl, 1);
|
|
@@ -2501,6 +2612,36 @@ DBKey db_str2key(const char *key)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Manual cast from 'int64' to the union DBKey.
|
|
|
|
+ * @param key Key to be casted
|
|
|
|
+ * @return The key as a DBKey union
|
|
|
|
+ * @public
|
|
|
|
+ */
|
|
|
|
+DBKey db_i642key(int64 key)
|
|
|
|
+{
|
|
|
|
+ DBKey ret;
|
|
|
|
+
|
|
|
|
+ DB_COUNTSTAT(db_i642key);
|
|
|
|
+ ret.i64 = key;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Manual cast from 'uin64' to the union DBKey.
|
|
|
|
+ * @param key Key to be casted
|
|
|
|
+ * @return The key as a DBKey union
|
|
|
|
+ * @public
|
|
|
|
+ */
|
|
|
|
+DBKey db_ui642key(uint64 key)
|
|
|
|
+{
|
|
|
|
+ DBKey ret;
|
|
|
|
+
|
|
|
|
+ DB_COUNTSTAT(db_ui642key);
|
|
|
|
+ ret.ui64 = key;
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Manual cast from 'int' to the struct DBData.
|
|
* Manual cast from 'int' to the struct DBData.
|
|
* @param data Data to be casted
|
|
* @param data Data to be casted
|
|
@@ -2620,11 +2761,15 @@ void db_final(void)
|
|
"DB_INT : allocated %10u, destroyed %10u\n"
|
|
"DB_INT : allocated %10u, destroyed %10u\n"
|
|
"DB_UINT : allocated %10u, destroyed %10u\n"
|
|
"DB_UINT : allocated %10u, destroyed %10u\n"
|
|
"DB_STRING : allocated %10u, destroyed %10u\n"
|
|
"DB_STRING : allocated %10u, destroyed %10u\n"
|
|
- "DB_ISTRING : allocated %10u, destroyed %10u\n",
|
|
|
|
|
|
+ "DB_ISTRING : allocated %10u, destroyed %10u\n"
|
|
|
|
+ "DB_INT64 : allocated %10u, destroyed %10u\n"
|
|
|
|
+ "DB_UINT64 : allocated %10u, destroyed %10u\n",
|
|
stats.db_int_alloc, stats.db_int_destroy,
|
|
stats.db_int_alloc, stats.db_int_destroy,
|
|
stats.db_uint_alloc, stats.db_uint_destroy,
|
|
stats.db_uint_alloc, stats.db_uint_destroy,
|
|
stats.db_string_alloc, stats.db_string_destroy,
|
|
stats.db_string_alloc, stats.db_string_destroy,
|
|
- stats.db_istring_alloc, stats.db_istring_destroy);
|
|
|
|
|
|
+ stats.db_istring_alloc, stats.db_istring_destroy,
|
|
|
|
+ stats.db_int64_alloc, stats.db_int64_destroy,
|
|
|
|
+ stats.db_uint64_alloc, stats.db_uint64_destroy);
|
|
ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n"
|
|
ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n"
|
|
"db_rotate_left %10u, db_rotate_right %10u,\n"
|
|
"db_rotate_left %10u, db_rotate_right %10u,\n"
|
|
"db_rebalance %10u, db_rebalance_erase %10u,\n"
|
|
"db_rebalance %10u, db_rebalance_erase %10u,\n"
|
|
@@ -2634,8 +2779,10 @@ void db_final(void)
|
|
"db_free_lock %10u, db_free_unlock %10u,\n"
|
|
"db_free_lock %10u, db_free_unlock %10u,\n"
|
|
"db_int_cmp %10u, db_uint_cmp %10u,\n"
|
|
"db_int_cmp %10u, db_uint_cmp %10u,\n"
|
|
"db_string_cmp %10u, db_istring_cmp %10u,\n"
|
|
"db_string_cmp %10u, db_istring_cmp %10u,\n"
|
|
|
|
+ "db_int64_cmp %10u, db_uint64_cmp %10u,\n"
|
|
"db_int_hash %10u, db_uint_hash %10u,\n"
|
|
"db_int_hash %10u, db_uint_hash %10u,\n"
|
|
"db_string_hash %10u, db_istring_hash %10u,\n"
|
|
"db_string_hash %10u, db_istring_hash %10u,\n"
|
|
|
|
+ "db_int64_hash %10u, db_uint64_hash %10u,\n"
|
|
"db_release_nothing %10u, db_release_key %10u,\n"
|
|
"db_release_nothing %10u, db_release_key %10u,\n"
|
|
"db_release_data %10u, db_release_both %10u,\n"
|
|
"db_release_data %10u, db_release_both %10u,\n"
|
|
"dbit_first %10u, dbit_last %10u,\n"
|
|
"dbit_first %10u, dbit_last %10u,\n"
|
|
@@ -2655,6 +2802,7 @@ void db_final(void)
|
|
"db_default_release %10u, db_custom_release %10u,\n"
|
|
"db_default_release %10u, db_custom_release %10u,\n"
|
|
"db_alloc %10u, db_i2key %10u,\n"
|
|
"db_alloc %10u, db_i2key %10u,\n"
|
|
"db_ui2key %10u, db_str2key %10u,\n"
|
|
"db_ui2key %10u, db_str2key %10u,\n"
|
|
|
|
+ "db_i642key %10u, db_ui642key %10u,\n"
|
|
"db_i2data %10u, db_ui2data %10u,\n"
|
|
"db_i2data %10u, db_ui2data %10u,\n"
|
|
"db_ptr2data %10u, db_data2i %10u,\n"
|
|
"db_ptr2data %10u, db_data2i %10u,\n"
|
|
"db_data2ui %10u, db_data2ptr %10u,\n"
|
|
"db_data2ui %10u, db_data2ptr %10u,\n"
|
|
@@ -2667,8 +2815,10 @@ void db_final(void)
|
|
stats.db_free_lock, stats.db_free_unlock,
|
|
stats.db_free_lock, stats.db_free_unlock,
|
|
stats.db_int_cmp, stats.db_uint_cmp,
|
|
stats.db_int_cmp, stats.db_uint_cmp,
|
|
stats.db_string_cmp, stats.db_istring_cmp,
|
|
stats.db_string_cmp, stats.db_istring_cmp,
|
|
|
|
+ stats.db_int64_cmp, stats.db_uint64_cmp,
|
|
stats.db_int_hash, stats.db_uint_hash,
|
|
stats.db_int_hash, stats.db_uint_hash,
|
|
stats.db_string_hash, stats.db_istring_hash,
|
|
stats.db_string_hash, stats.db_istring_hash,
|
|
|
|
+ stats.db_int64_hash, stats.db_uint64_hash,
|
|
stats.db_release_nothing, stats.db_release_key,
|
|
stats.db_release_nothing, stats.db_release_key,
|
|
stats.db_release_data, stats.db_release_both,
|
|
stats.db_release_data, stats.db_release_both,
|
|
stats.dbit_first, stats.dbit_last,
|
|
stats.dbit_first, stats.dbit_last,
|
|
@@ -2688,6 +2838,7 @@ void db_final(void)
|
|
stats.db_default_release, stats.db_custom_release,
|
|
stats.db_default_release, stats.db_custom_release,
|
|
stats.db_alloc, stats.db_i2key,
|
|
stats.db_alloc, stats.db_i2key,
|
|
stats.db_ui2key, stats.db_str2key,
|
|
stats.db_ui2key, stats.db_str2key,
|
|
|
|
+ stats.db_i642key, stats.db_ui642key,
|
|
stats.db_i2data, stats.db_ui2data,
|
|
stats.db_i2data, stats.db_ui2data,
|
|
stats.db_ptr2data, stats.db_data2i,
|
|
stats.db_ptr2data, stats.db_data2i,
|
|
stats.db_data2ui, stats.db_data2ptr,
|
|
stats.db_data2ui, stats.db_data2ptr,
|