diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 12 | ||||
-rw-r--r-- | src/common/cbasetypes.h | 18 | ||||
-rw-r--r-- | src/common/console.c | 12 | ||||
-rw-r--r-- | src/common/core.c | 14 | ||||
-rw-r--r-- | src/common/db.c | 2026 | ||||
-rw-r--r-- | src/common/db.h | 90 | ||||
-rw-r--r-- | src/common/des.c | 10 | ||||
-rw-r--r-- | src/common/ers.c | 117 | ||||
-rw-r--r-- | src/common/ers.h | 6 | ||||
-rw-r--r-- | src/common/grfio.c | 14 | ||||
-rw-r--r-- | src/common/malloc.c | 152 | ||||
-rw-r--r-- | src/common/malloc.h | 16 | ||||
-rw-r--r-- | src/common/mapindex.c | 2 | ||||
-rw-r--r-- | src/common/mapindex.h | 2 | ||||
-rw-r--r-- | src/common/mmo.h | 68 | ||||
-rw-r--r-- | src/common/mutex.c | 2 | ||||
-rw-r--r-- | src/common/random.c | 2 | ||||
-rw-r--r-- | src/common/socket.c | 72 | ||||
-rw-r--r-- | src/common/socket.h | 14 | ||||
-rw-r--r-- | src/common/sql.c | 4 | ||||
-rw-r--r-- | src/common/timer.c | 37 | ||||
-rw-r--r-- | src/common/timer.h | 39 |
22 files changed, 1468 insertions, 1261 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 28ea8f413..ed6151c95 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -264,8 +264,8 @@ void hplugins_share_defaults(void) { HPM->share(&SERVER_TYPE,"SERVER_TYPE"); HPM->share((void*)get_svn_revision,"get_svn_revision"); HPM->share((void*)get_git_hash,"get_git_hash"); - HPM->share(DB, "DB"); - HPM->share(malloclib, "malloclib"); + HPM->share(iDB, "iDB"); + HPM->share(iMalloc, "iMalloc"); /* socket */ HPM->share(RFIFOSKIP,"RFIFOSKIP"); HPM->share(WFIFOSET,"WFIFOSET"); @@ -281,12 +281,8 @@ void hplugins_share_defaults(void) { /* sql */ HPM->share(SQL,"SQL"); /* timer */ - HPM->share(gettick,"gettick"); - HPM->share(add_timer,"add_timer"); - HPM->share(add_timer_interval,"add_timer_interval"); - HPM->share(add_timer_func_list,"add_timer_func_list"); - HPM->share(delete_timer,"delete_timer"); - HPM->share(get_uptime,"get_uptime"); + HPM->share(iTimer,"iTimer"); + } CPCMD(plugins) { if( HPM->plugin_count == 0 ) { diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 731a8b578..bfe8bf8f8 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -281,6 +281,24 @@ typedef char bool; //#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b))) // Avoid "value computed is not used" warning and generates the same assembly code #define swap(a,b) if (a != b) ((a ^= b), (b ^= a), (a ^= b)) +#if 0 //to be activated soon, more tests needed on how VS works with the macro above +#ifdef WIN32 +#undef swap +#define swap(a,b)__asm \ +{ \ + __asm mov eax, dword ptr [a] \ + __asm cmp eax, dword ptr [b] \ + __asm je _ret \ + __asm xor eax, dword ptr [b] \ + __asm mov dword ptr [a], eax \ + __asm xor eax, dword ptr [b] \ + __asm mov dword ptr [b], eax \ + __asm xor eax, dword ptr [a] \ + __asm mov dword ptr [a], eax \ + __asm _ret: \ +} +#endif +#endif #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/src/common/console.c b/src/common/console.c index ba93b8e09..08daec04e 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -85,6 +85,9 @@ CPCMD(exit) { CPCMD(ers_report) { ers_report(); } +CPCMD(mem_report) { + memmgr_report(line?atoi(line):0); +} CPCMD(help) { unsigned int i = 0; for ( i = 0; i < console->cmd_list_count; i++ ) { @@ -98,7 +101,7 @@ CPCMD(help) { } /* [Ind/Hercules] */ CPCMD(malloc_usage) { - unsigned int val = (unsigned int)malloclib->usage(); + unsigned int val = (unsigned int)iMalloc->usage(); ShowInfo("malloc_usage: %.2f MB\n",(double)(val)/1024); } #define CP_DEF_C(x) { #x , NULL , NULL, NULL } @@ -115,6 +118,7 @@ void console_load_defaults(void) { CP_DEF(help), CP_DEF_C(server), CP_DEF_S(ers_report,server), + CP_DEF_S(mem_report,server), CP_DEF_S(malloc_usage,server), CP_DEF_S(exit,server), }; @@ -227,8 +231,10 @@ void console_parse_sub(char *line) { char *tok; char sublist[CP_CMD_LENGTH * 5]; unsigned int i, len = 0; + memcpy(bline, line, 200); tok = strtok(line, " "); + for ( i = 0; i < console->cmd_list_count; i++ ) { if( strcmpi(tok,console->cmd_list[i]->cmd) == 0 ) break; @@ -363,8 +369,8 @@ void console_parse_init(void) { exit(EXIT_FAILURE); } - add_timer_func_list(console->parse_timer, "console_parse_timer"); - add_timer_interval(gettick() + 1000, console->parse_timer, 0, 0, 500);/* start listening in 1s; re-try every 0.5s */ + iTimer->add_timer_func_list(console->parse_timer, "console_parse_timer"); + iTimer->add_timer_interval(iTimer->gettick() + 1000, console->parse_timer, 0, 0, 500);/* start listening in 1s; re-try every 0.5s */ } #endif /* CONSOLE_INPUT */ diff --git a/src/common/core.c b/src/common/core.c index 0959e6fc9..d6cfff662 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -307,7 +307,7 @@ int main (int argc, char **argv) { } core_defaults(); - malloclib->init();// needed for Show* in display_title() [FlavioJS] + iMalloc->init();// needed for Show* in display_title() [FlavioJS] console->display_title(); @@ -322,14 +322,14 @@ int main (int argc, char **argv) { Sql_Init(); rathread_init(); mempool_init(); - DB->init(); + iDB->init(); signals_init(); #ifdef _WIN32 cevents_init(); #endif - timer_init(); + iTimer->init(); console->init(); @@ -343,7 +343,7 @@ int main (int argc, char **argv) { {// Main runtime cycle int next; while (runflag != CORE_ST_STOP) { - next = do_timer(gettick_nocache()); + next = iTimer->do_timer(iTimer->gettick_nocache()); do_sockets(next); } } @@ -354,14 +354,14 @@ int main (int argc, char **argv) { #ifndef MINICORE HPM->final(); #endif - timer_final(); + iTimer->final(); socket_final(); - DB->final(); + iDB->final(); mempool_final(); rathread_final(); #endif - malloclib->final(); + iMalloc->final(); return 0; } diff --git a/src/common/db.c b/src/common/db.c index 579697a99..b1fe22a4a 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -1,70 +1,70 @@ /*****************************************************************************\ -* Copyright (c) Athena Dev Teams - Licensed under GNU GPL -* For more information, see LICENCE in the main folder -* -* This file is separated in five sections: -* (1) Private typedefs, enums, structures, defines and gblobal variables -* (2) Private functions -* (3) Protected functions used internally -* (4) Protected functions used in the interface of the database -* (5) Public functions -* -* The databases are structured as a hashtable of RED-BLACK trees. -* -* <B>Properties of the RED-BLACK trees being used:</B> -* 1. The value of any node is greater than the value of its left child and -* less than the value of its right child. -* 2. Every node is colored either RED or BLACK. -* 3. Every red node that is not a leaf has only black children. -* 4. Every path from the root to a leaf contains the same number of black -* nodes. -* 5. The root node is black. -* An <code>n</code> node in a RED-BLACK tree has the property that its -* height is <code>O(lg(n))</code>. -* Another important property is that after adding a node to a RED-BLACK -* tree, the tree can be readjusted in <code>O(lg(n))</code> time. -* Similarly, after deleting a node from a RED-BLACK tree, the tree can be -* readjusted in <code>O(lg(n))</code> time. -* {@link http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic18/} -* -* <B>How to add new database types:</B> -* 1. Add the identifier of the new database type to the enum DBType -* 2. If not already there, add the data type of the key to the union DBKey -* 3. If the key can be considered NULL, update the function db_is_key_null -* 4. If the key can be duplicated, update the functions db_dup_key and -* db_dup_key_free -* 5. Create a comparator and update the function db_default_cmp -* 6. Create a hasher and update the function db_default_hash -* 7. If the new database type requires or does not support some options, -* update the function db_fix_options -* -* TODO: -* - create test cases to test the database system thoroughly -* - finish this header describing the database system -* - create custom database allocator -* - make the system thread friendly -* - change the structure of the database to T-Trees -* - create a db that organizes itself by splaying -* -* HISTORY: -* 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] -* 2012/03/09 - Added enum for data types (int, uint, void*) -* 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. -* 2007/11/09 - Added an iterator to the database. -* 2006/12/21 - Added 1-node cache to the database. -* 2.1 (Athena build #???#) - Portability fix -* - Fixed the portability of casting to union and added the functions -* ensure and clear to the database. -* 2.0 (Athena build 4859) - Transition version -* - Almost everything recoded with a strategy similar to objects, -* database structure is maintained. -* 1.0 (up to Athena build 4706) -* - Previous database system. -* -* @version 2006/12/21 -* @author Athena Dev team -* @encoding US-ASCII -* @see #db.h + * Copyright (c) Athena Dev Teams - Licensed under GNU GPL + * For more information, see LICENCE in the main folder + * + * This file is separated in five sections: + * (1) Private typedefs, enums, structures, defines and gblobal variables + * (2) Private functions + * (3) Protected functions used internally + * (4) Protected functions used in the interface of the database + * (5) Public functions + * + * The databases are structured as a hashtable of RED-BLACK trees. + * + * <B>Properties of the RED-BLACK trees being used:</B> + * 1. The value of any node is greater than the value of its left child and + * less than the value of its right child. + * 2. Every node is colored either RED or BLACK. + * 3. Every red node that is not a leaf has only black children. + * 4. Every path from the root to a leaf contains the same number of black + * nodes. + * 5. The root node is black. + * An <code>n</code> node in a RED-BLACK tree has the property that its + * height is <code>O(lg(n))</code>. + * Another important property is that after adding a node to a RED-BLACK + * tree, the tree can be readjusted in <code>O(lg(n))</code> time. + * Similarly, after deleting a node from a RED-BLACK tree, the tree can be + * readjusted in <code>O(lg(n))</code> time. + * {@link http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic18/} + * + * <B>How to add new database types:</B> + * 1. Add the identifier of the new database type to the enum DBType + * 2. If not already there, add the data type of the key to the union DBKey + * 3. If the key can be considered NULL, update the function db_is_key_null + * 4. If the key can be duplicated, update the functions db_dup_key and + * db_dup_key_free + * 5. Create a comparator and update the function db_default_cmp + * 6. Create a hasher and update the function db_default_hash + * 7. If the new database type requires or does not support some options, + * update the function db_fix_options + * + * TODO: + * - create test cases to test the database system thoroughly + * - finish this header describing the database system + * - create custom database allocator + * - make the system thread friendly + * - change the structure of the database to T-Trees + * - create a db that organizes itself by splaying + * + * HISTORY: + * 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] + * 2012/03/09 - Added enum for data types (int, uint, void*) + * 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. + * 2007/11/09 - Added an iterator to the database. + * 2006/12/21 - Added 1-node cache to the database. + * 2.1 (Athena build #???#) - Portability fix + * - Fixed the portability of casting to union and added the functions + * ensure and clear to the database. + * 2.0 (Athena build 4859) - Transition version + * - Almost everything recoded with a strategy similar to objects, + * database structure is maintained. + * 1.0 (up to Athena build 4706) + * - Previous database system. + * + * @version 2006/12/21 + * @author Athena Dev team + * @encoding US-ASCII + * @see #db.h \*****************************************************************************/ #include <stdio.h> #include <stdlib.h> @@ -77,58 +77,58 @@ #include "../common/strlib.h" /*****************************************************************************\ -* (1) Private typedefs, enums, structures, defines and global variables of * -* the database system. * -* DB_ENABLE_STATS - Define to enable database statistics. * -* HASH_SIZE - Define with the size of the hashtable. * -* DBNColor - Enumeration of colors of the nodes. * -* DBNode - Structure of a node in RED-BLACK trees. * -* struct db_free - Structure that holds a deleted node to be freed. * -* DBMap_impl - Struture of the database. * -* stats - Statistics about the database system. * + * (1) Private typedefs, enums, structures, defines and global variables of * + * the database system. * + * DB_ENABLE_STATS - Define to enable database statistics. * + * HASH_SIZE - Define with the size of the hashtable. * + * DBNColor - Enumeration of colors of the nodes. * + * DBNode - Structure of a node in RED-BLACK trees. * + * struct db_free - Structure that holds a deleted node to be freed. * + * DBMap_impl - Struture of the database. * + * 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 -* system. -* WARNING: This adds overhead to every database operation (not shure how much). -* @private -* @see #DBStats -* @see #stats -* @see #db_final(void) -*/ + * If defined statistics about database nodes, database creating/destruction + * and function usage are keept and displayed when finalizing the database + * system. + * WARNING: This adds overhead to every database operation (not shure how much). + * @private + * @see #DBStats + * @see #stats + * @see #db_final(void) + */ //#define DB_ENABLE_STATS /** -* Size of the hashtable in the database. -* @private -* @see DBMap_impl#ht -*/ + * Size of the hashtable in the database. + * @private + * @see DBMap_impl#ht + */ #define HASH_SIZE (256+27) /** -* The color of individual nodes. -* @private -* @see struct dbn -*/ + * The color of individual nodes. + * @private + * @see struct dbn + */ typedef enum node_color { RED, BLACK } node_color; /** -* A node in a RED-BLACK tree of the database. -* @param parent Parent node -* @param left Left child node -* @param right Right child node -* @param key Key of this database entry -* @param data Data of this database entry -* @param deleted If the node is deleted -* @param color Color of the node -* @private -* @see DBMap_impl#ht -*/ + * A node in a RED-BLACK tree of the database. + * @param parent Parent node + * @param left Left child node + * @param right Right child node + * @param key Key of this database entry + * @param data Data of this database entry + * @param deleted If the node is deleted + * @param color Color of the node + * @private + * @see DBMap_impl#ht + */ typedef struct dbn { // Tree structure struct dbn *parent; @@ -143,39 +143,39 @@ typedef struct dbn { } *DBNode; /** -* Structure that holds a deleted node. -* @param node Deleted node -* @param root Address to the root of the tree -* @private -* @see DBMap_impl#free_list -*/ + * Structure that holds a deleted node. + * @param node Deleted node + * @param root Address to the root of the tree + * @private + * @see DBMap_impl#free_list + */ struct db_free { DBNode node; DBNode *root; }; /** -* Complete database structure. -* @param vtable Interface of the database -* @param alloc_file File where the database was allocated -* @param alloc_line Line in the file where the database was allocated -* @param free_list Array of deleted nodes to be freed -* @param free_count Number of deleted nodes in free_list -* @param free_max Current maximum capacity of free_list -* @param free_lock Lock for freeing the nodes -* @param nodes Manager of reusable tree nodes -* @param cmp Comparator of the database -* @param hash Hasher of the database -* @param release Releaser of the database -* @param ht Hashtable of RED-BLACK trees -* @param type Type of the database -* @param options Options of the database -* @param item_count Number of items in the database -* @param maxlen Maximum length of strings in DB_STRING and DB_ISTRING databases -* @param global_lock Global lock of the database -* @private -* @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short) -*/ + * Complete database structure. + * @param vtable Interface of the database + * @param alloc_file File where the database was allocated + * @param alloc_line Line in the file where the database was allocated + * @param free_list Array of deleted nodes to be freed + * @param free_count Number of deleted nodes in free_list + * @param free_max Current maximum capacity of free_list + * @param free_lock Lock for freeing the nodes + * @param nodes Manager of reusable tree nodes + * @param cmp Comparator of the database + * @param hash Hasher of the database + * @param release Releaser of the database + * @param ht Hashtable of RED-BLACK trees + * @param type Type of the database + * @param options Options of the database + * @param item_count Number of items in the database + * @param maxlen Maximum length of strings in DB_STRING and DB_ISTRING databases + * @param global_lock Global lock of the database + * @private + * @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short) + */ typedef struct DBMap_impl { // Database interface struct DBMap vtable; @@ -202,16 +202,16 @@ typedef struct DBMap_impl { } DBMap_impl; /** -* Complete iterator structure. -* @param vtable Interface of the iterator -* @param db Parent database -* @param ht_index Current index of the hashtable -* @param node Current node -* @private -* @see #DBIterator -* @see #DBMap_impl -* @see #DBNode -*/ + * Complete iterator structure. + * @param vtable Interface of the iterator + * @param db Parent database + * @param ht_index Current index of the hashtable + * @param node Current node + * @private + * @see #DBIterator + * @see #DBMap_impl + * @see #DBNode + */ typedef struct DBIterator_impl { // Iterator interface struct DBIterator vtable; @@ -222,11 +222,11 @@ typedef struct DBIterator_impl { #if defined(DB_ENABLE_STATS) /** -* Structure with what is counted when the database statistics are enabled. -* @private -* @see #DB_ENABLE_STATS -* @see #stats -*/ + * Structure with what is counted when the database statistics are enabled. + * @private + * @see #DB_ENABLE_STATS + * @see #stats + */ static struct db_stats { // Node alloc/free uint32 db_node_alloc; @@ -325,30 +325,30 @@ struct eri *db_iterator_ers; struct eri *db_alloc_ers; /*****************************************************************************\ -* (2) Section of private functions used by the database system. * -* db_rotate_left - Rotate a tree node to the left. * -* db_rotate_right - Rotate a tree node to the right. * -* db_rebalance - Rebalance the tree. * -* db_rebalance_erase - Rebalance the tree after a BLACK node was erased. * -* db_is_key_null - Returns not 0 if the key is considered NULL. * -* db_dup_key - Duplicate a key for internal use. * -* db_dup_key_free - Free the duplicated key. * -* db_free_add - Add a node to the free_list of a database. * -* db_free_remove - Remove a node from the free_list of a database. * -* db_free_lock - Increment the free_lock of a database. * -* db_free_unlock - Decrement the free_lock of a database. * -* If it was the last lock, frees the nodes in free_list. * -* NOTE: Keeps the database trees balanced. * + * (2) Section of private functions used by the database system. * + * db_rotate_left - Rotate a tree node to the left. * + * db_rotate_right - Rotate a tree node to the right. * + * db_rebalance - Rebalance the tree. * + * db_rebalance_erase - Rebalance the tree after a BLACK node was erased. * + * db_is_key_null - Returns not 0 if the key is considered NULL. * + * db_dup_key - Duplicate a key for internal use. * + * db_dup_key_free - Free the duplicated key. * + * db_free_add - Add a node to the free_list of a database. * + * db_free_remove - Remove a node from the free_list of a database. * + * db_free_lock - Increment the free_lock of a database. * + * db_free_unlock - Decrement the free_lock of a database. * + * If it was the last lock, frees the nodes in free_list. * + * NOTE: Keeps the database trees balanced. * \*****************************************************************************/ /** -* Rotate a node to the left. -* @param node Node to be rotated -* @param root Pointer to the root of the tree -* @private -* @see #db_rebalance(DBNode,DBNode *) -* @see #db_rebalance_erase(DBNode,DBNode *) -*/ + * Rotate a node to the left. + * @param node Node to be rotated + * @param root Pointer to the root of the tree + * @private + * @see #db_rebalance(DBNode,DBNode *) + * @see #db_rebalance_erase(DBNode,DBNode *) + */ static void db_rotate_left(DBNode node, DBNode *root) { DBNode y = node->right; @@ -373,13 +373,13 @@ static void db_rotate_left(DBNode node, DBNode *root) } /** -* Rotate a node to the right -* @param node Node to be rotated -* @param root Pointer to the root of the tree -* @private -* @see #db_rebalance(DBNode,DBNode *) -* @see #db_rebalance_erase(DBNode,DBNode *) -*/ + * Rotate a node to the right + * @param node Node to be rotated + * @param root Pointer to the root of the tree + * @private + * @see #db_rebalance(DBNode,DBNode *) + * @see #db_rebalance_erase(DBNode,DBNode *) + */ static void db_rotate_right(DBNode node, DBNode *root) { DBNode y = node->left; @@ -404,15 +404,15 @@ static void db_rotate_right(DBNode node, DBNode *root) } /** -* Rebalance the RED-BLACK tree. -* Called when the node and it's parent are both RED. -* @param node Node to be rebalanced -* @param root Pointer to the root of the tree -* @private -* @see #db_rotate_left(DBNode,DBNode *) -* @see #db_rotate_right(DBNode,DBNode *) -* @see #db_obj_put(DBMap*,DBKey,DBData) -*/ + * Rebalance the RED-BLACK tree. + * Called when the node and it's parent are both RED. + * @param node Node to be rebalanced + * @param root Pointer to the root of the tree + * @private + * @see #db_rotate_left(DBNode,DBNode *) + * @see #db_rotate_right(DBNode,DBNode *) + * @see #db_obj_put(DBMap*,DBKey,DBData) + */ static void db_rebalance(DBNode node, DBNode *root) { DBNode y; @@ -467,14 +467,14 @@ static void db_rebalance(DBNode node, DBNode *root) } /** -* Erase a node from the RED-BLACK tree, keeping the tree balanced. -* @param node Node to be erased from the tree -* @param root Root of the tree -* @private -* @see #db_rotate_left(DBNode,DBNode *) -* @see #db_rotate_right(DBNode,DBNode *) -* @see #db_free_unlock(DBMap_impl*) -*/ + * Erase a node from the RED-BLACK tree, keeping the tree balanced. + * @param node Node to be erased from the tree + * @param root Root of the tree + * @private + * @see #db_rotate_left(DBNode,DBNode *) + * @see #db_rotate_right(DBNode,DBNode *) + * @see #db_free_unlock(DBMap_impl*) + */ static void db_rebalance_erase(DBNode node, DBNode *root) { DBNode y = node; @@ -558,9 +558,9 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } if ((w->left == NULL || w->left->color == BLACK) && (w->right == NULL || w->right->color == BLACK)) { - w->color = RED; - x = x_parent; - x_parent = x_parent->parent; + w->color = RED; + x = x_parent; + x_parent = x_parent->parent; } else { if (w->right == NULL || w->right->color == BLACK) { if (w->left) w->left->color = BLACK; @@ -584,9 +584,9 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } if ((w->right == NULL || w->right->color == BLACK) && (w->left == NULL || w->left->color == BLACK)) { - w->color = RED; - x = x_parent; - x_parent = x_parent->parent; + w->color = RED; + x = x_parent; + x_parent = x_parent->parent; } else { if (w->left == NULL || w->left->color == BLACK) { if (w->right) w->right->color = BLACK; @@ -607,39 +607,39 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } /** -* Returns not 0 if the key is considered to be NULL. -* @param type Type of database -* @param key Key being tested -* @return not 0 if considered NULL, 0 otherwise -* @private -* @see #db_obj_get(DBMap*,DBKey) -* @see #db_obj_put(DBMap*,DBKey,DBData) -* @see #db_obj_remove(DBMap*,DBKey) -*/ + * Returns not 0 if the key is considered to be NULL. + * @param type Type of database + * @param key Key being tested + * @return not 0 if considered NULL, 0 otherwise + * @private + * @see #db_obj_get(DBMap*,DBKey) + * @see #db_obj_put(DBMap*,DBKey,DBData) + * @see #db_obj_remove(DBMap*,DBKey) + */ static int db_is_key_null(DBType type, DBKey key) { DB_COUNTSTAT(db_is_key_null); switch (type) { - case DB_STRING: - case DB_ISTRING: - return (key.str == NULL); + case DB_STRING: + case DB_ISTRING: + return (key.str == NULL); - default: // Not a pointer - return 0; + default: // Not a pointer + return 0; } } /** -* Duplicate the key used in the database. -* @param db Database the key is being used in -* @param key Key to be duplicated -* @param Duplicated key -* @private -* @see #db_free_add(DBMap_impl*,DBNode,DBNode *) -* @see #db_free_remove(DBMap_impl*,DBNode) -* @see #db_obj_put(DBMap*,DBKey,void *) -* @see #db_dup_key_free(DBMap_impl*,DBKey) -*/ + * Duplicate the key used in the database. + * @param db Database the key is being used in + * @param key Key to be duplicated + * @param Duplicated key + * @private + * @see #db_free_add(DBMap_impl*,DBNode,DBNode *) + * @see #db_free_remove(DBMap_impl*,DBNode) + * @see #db_obj_put(DBMap*,DBKey,void *) + * @see #db_dup_key_free(DBMap_impl*,DBKey) + */ static DBKey db_dup_key(DBMap_impl* db, DBKey key) { char *str; @@ -647,56 +647,56 @@ static DBKey db_dup_key(DBMap_impl* db, DBKey key) DB_COUNTSTAT(db_dup_key); switch (db->type) { - case DB_STRING: - case DB_ISTRING: - len = strnlen(key.str, db->maxlen); - str = (char*)aMalloc(len + 1); - memcpy(str, key.str, len); - str[len] = '\0'; - key.str = str; - return key; - - default: - return key; + case DB_STRING: + case DB_ISTRING: + len = strnlen(key.str, db->maxlen); + str = (char*)aMalloc(len + 1); + memcpy(str, key.str, len); + str[len] = '\0'; + key.str = str; + return key; + + default: + return key; } } /** -* Free a key duplicated by db_dup_key. -* @param db Database the key is being used in -* @param key Key to be freed -* @private -* @see #db_dup_key(DBMap_impl*,DBKey) -*/ + * Free a key duplicated by db_dup_key. + * @param db Database the key is being used in + * @param key Key to be freed + * @private + * @see #db_dup_key(DBMap_impl*,DBKey) + */ static void db_dup_key_free(DBMap_impl* db, DBKey key) { DB_COUNTSTAT(db_dup_key_free); switch (db->type) { - case DB_STRING: - case DB_ISTRING: - aFree((char*)key.str); - return; + case DB_STRING: + case DB_ISTRING: + aFree((char*)key.str); + return; - default: - return; + default: + return; } } /** -* Add a node to the free_list of the database. -* Marks the node as deleted. -* If the key isn't duplicated, the key is duplicated and released. -* @param db Target database -* @param root Root of the tree from the node -* @param node Target node -* @private -* @see #struct db_free -* @see DBMap_impl#free_list -* @see DBMap_impl#free_count -* @see DBMap_impl#free_max -* @see #db_obj_remove(DBMap*,DBKey) -* @see #db_free_remove(DBMap_impl*,DBNode) -*/ + * Add a node to the free_list of the database. + * Marks the node as deleted. + * If the key isn't duplicated, the key is duplicated and released. + * @param db Target database + * @param root Root of the tree from the node + * @param node Target node + * @private + * @see #struct db_free + * @see DBMap_impl#free_list + * @see DBMap_impl#free_count + * @see DBMap_impl#free_max + * @see #db_obj_remove(DBMap*,DBKey) + * @see #db_free_remove(DBMap_impl*,DBNode) + */ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) { DBKey old_key; @@ -704,8 +704,8 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) DB_COUNTSTAT(db_free_add); if (db->free_lock == (unsigned int)~0) { ShowFatalError("db_free_add: free_lock overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } if (!(db->options&DB_OPT_DUP_KEY)) { // Make sure we have a key until the node is freed @@ -718,8 +718,8 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) if (db->free_max <= db->free_count) { if (db->free_count == (unsigned int)~0) { ShowFatalError("db_free_add: free_count overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } db->free_max = (unsigned int)~0; @@ -734,18 +734,18 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) } /** -* Remove a node from the free_list of the database. -* Marks the node as not deleted. -* NOTE: Frees the duplicated key of the node. -* @param db Target database -* @param node Node being removed from free_list -* @private -* @see #struct db_free -* @see DBMap_impl#free_list -* @see DBMap_impl#free_count -* @see #db_obj_put(DBMap*,DBKey,DBData) -* @see #db_free_add(DBMap_impl*,DBNode*,DBNode) -*/ + * Remove a node from the free_list of the database. + * Marks the node as not deleted. + * NOTE: Frees the duplicated key of the node. + * @param db Target database + * @param node Node being removed from free_list + * @private + * @see #struct db_free + * @see DBMap_impl#free_list + * @see DBMap_impl#free_count + * @see #db_obj_put(DBMap*,DBKey,DBData) + * @see #db_free_add(DBMap_impl*,DBNode*,DBNode) + */ static void db_free_remove(DBMap_impl* db, DBNode node) { unsigned int i; @@ -769,35 +769,35 @@ static void db_free_remove(DBMap_impl* db, DBNode node) } /** -* Increment the free_lock of the database. -* @param db Target database -* @private -* @see DBMap_impl#free_lock -* @see #db_unlock(DBMap_impl*) -*/ + * Increment the free_lock of the database. + * @param db Target database + * @private + * @see DBMap_impl#free_lock + * @see #db_unlock(DBMap_impl*) + */ static void db_free_lock(DBMap_impl* db) { DB_COUNTSTAT(db_free_lock); if (db->free_lock == (unsigned int)~0) { ShowFatalError("db_free_lock: free_lock overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } db->free_lock++; } /** -* Decrement the free_lock of the database. -* If it was the last lock, frees the nodes of the database. -* Keeps the tree balanced. -* NOTE: Frees the duplicated keys of the nodes -* @param db Target database -* @private -* @see DBMap_impl#free_lock -* @see #db_free_dbn(DBNode) -* @see #db_lock(DBMap_impl*) -*/ + * Decrement the free_lock of the database. + * If it was the last lock, frees the nodes of the database. + * Keeps the tree balanced. + * NOTE: Frees the duplicated keys of the nodes + * @param db Target database + * @private + * @see DBMap_impl#free_lock + * @see #db_free_dbn(DBNode) + * @see #db_lock(DBMap_impl*) + */ static void db_free_unlock(DBMap_impl* db) { unsigned int i; @@ -805,8 +805,8 @@ static void db_free_unlock(DBMap_impl* db) DB_COUNTSTAT(db_free_unlock); if (db->free_lock == 0) { ShowWarning("db_free_unlock: free_lock was already 0\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); } else { db->free_lock--; } @@ -823,36 +823,36 @@ static void db_free_unlock(DBMap_impl* db) } /*****************************************************************************\ -* (3) Section of protected functions used internally. * -* NOTE: the protected functions used in the database interface are in the * -* next section. * -* db_int_cmp - Default comparator for DB_INT databases. * -* db_uint_cmp - Default comparator for DB_UINT databases. * -* db_string_cmp - Default comparator for DB_STRING databases. * -* db_istring_cmp - Default comparator for DB_ISTRING databases. * -* db_int_hash - Default hasher for DB_INT databases. * -* db_uint_hash - Default hasher for DB_UINT databases. * -* db_string_hash - Default hasher for DB_STRING databases. * -* db_istring_hash - Default hasher for DB_ISTRING databases. * -* db_release_nothing - Releaser that releases nothing. * -* db_release_key - Releaser that only releases the key. * -* db_release_data - Releaser that only releases the data. * -* db_release_both - Releaser that releases key and data. * + * (3) Section of protected functions used internally. * + * NOTE: the protected functions used in the database interface are in the * + * next section. * + * db_int_cmp - Default comparator for DB_INT databases. * + * db_uint_cmp - Default comparator for DB_UINT databases. * + * db_string_cmp - Default comparator for DB_STRING databases. * + * db_istring_cmp - Default comparator for DB_ISTRING databases. * + * db_int_hash - Default hasher for DB_INT databases. * + * db_uint_hash - Default hasher for DB_UINT databases. * + * db_string_hash - Default hasher for DB_STRING databases. * + * db_istring_hash - Default hasher for DB_ISTRING databases. * + * db_release_nothing - Releaser that releases nothing. * + * db_release_key - Releaser that only releases the key. * + * db_release_data - Releaser that only releases the data. * + * db_release_both - Releaser that releases key and data. * \*****************************************************************************/ /** -* Default comparator for DB_INT 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_INT -* @see #DBComparator -* @see #db_default_cmp(DBType) -*/ + * Default comparator for DB_INT 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_INT + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { (void)maxlen;//not used @@ -863,18 +863,18 @@ static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** -* Default comparator for DB_UINT 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_UINT -* @see #DBComparator -* @see #db_default_cmp(DBType) -*/ + * Default comparator for DB_UINT 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_UINT + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { (void)maxlen;//not used @@ -885,17 +885,17 @@ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** -* Default comparator for DB_STRING databases. -* Compares key1 to key2. -* Return 0 if equal, negative if lower and positive if higher. -* @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_STRING -* @see #DBComparator -* @see #db_default_cmp(DBType) -*/ + * Default comparator for DB_STRING databases. + * Compares key1 to key2. + * Return 0 if equal, negative if lower and positive if higher. + * @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_STRING + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { DB_COUNTSTAT(db_string_cmp); @@ -903,17 +903,17 @@ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** -* Default comparator for DB_ISTRING databases. -* Compares key1 to key2 case insensitively. -* Return 0 if equal, negative if lower and positive if higher. -* @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_ISTRING -* @see #DBComparator -* @see #db_default_cmp(DBType) -*/ + * Default comparator for DB_ISTRING databases. + * Compares key1 to key2 case insensitively. + * Return 0 if equal, negative if lower and positive if higher. + * @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_ISTRING + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { DB_COUNTSTAT(db_istring_cmp); @@ -921,16 +921,16 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** -* Default hasher for DB_INT 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_INT -* @see #DBHasher -* @see #db_default_hash(DBType) -*/ + * Default hasher for DB_INT 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_INT + * @see #DBHasher + * @see #db_default_hash(DBType) + */ static unsigned int db_int_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used @@ -939,16 +939,16 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen) } /** -* Default hasher for DB_UINT 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_UINT -* @see #DBHasher -* @see #db_default_hash(DBType) -*/ + * Default hasher for DB_UINT 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_UINT + * @see #DBHasher + * @see #db_default_hash(DBType) + */ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used @@ -957,14 +957,14 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) } /** -* Default hasher for DB_STRING databases. -* @param key Key to be hashed -* @param maxlen Maximum length of the key to hash -* @return hash of the key -* @see DBType#DB_STRING -* @see #DBHasher -* @see #db_default_hash(DBType) -*/ + * Default hasher for DB_STRING databases. + * @param key Key to be hashed + * @param maxlen Maximum length of the key to hash + * @return hash of the key + * @see DBType#DB_STRING + * @see #DBHasher + * @see #db_default_hash(DBType) + */ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; @@ -984,13 +984,13 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) } /** -* Default hasher for DB_ISTRING databases. -* @param key Key to be hashed -* @param maxlen Maximum length of the key to hash -* @return hash of the key -* @see DBType#DB_ISTRING -* @see #db_default_hash(DBType) -*/ + * Default hasher for DB_ISTRING databases. + * @param key Key to be hashed + * @param maxlen Maximum length of the key to hash + * @return hash of the key + * @see DBType#DB_ISTRING + * @see #db_default_hash(DBType) + */ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; @@ -1010,14 +1010,14 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) } /** -* Releaser that releases nothing. -* @param key Key of the database entry -* @param data Data of the database entry -* @param which What is being requested to be released -* @protected -* @see #DBReleaser -* @see #db_default_releaser(DBType,DBOptions) -*/ + * Releaser that releases nothing. + * @param key Key of the database entry + * @param data Data of the database entry + * @param which What is being requested to be released + * @protected + * @see #DBReleaser + * @see #db_default_releaser(DBType,DBOptions) + */ static void db_release_nothing(DBKey key, DBData data, DBRelease which) { (void)key;(void)data;(void)which;//not used @@ -1025,14 +1025,14 @@ static void db_release_nothing(DBKey key, DBData data, DBRelease which) } /** -* Releaser that only releases the key. -* @param key Key of the database entry -* @param data Data of the database entry -* @param which What is being requested to be released -* @protected -* @see #DBReleaser -* @see #db_default_release(DBType,DBOptions) -*/ + * Releaser that only releases the key. + * @param key Key of the database entry + * @param data Data of the database entry + * @param which What is being requested to be released + * @protected + * @see #DBReleaser + * @see #db_default_release(DBType,DBOptions) + */ static void db_release_key(DBKey key, DBData data, DBRelease which) { (void)data;//not used @@ -1041,16 +1041,16 @@ static void db_release_key(DBKey key, DBData data, DBRelease which) } /** -* Releaser that only releases the data. -* @param key Key of the database entry -* @param data Data of the database entry -* @param which What is being requested to be released -* @protected -* @see #DBData -* @see #DBRelease -* @see #DBReleaser -* @see #db_default_release(DBType,DBOptions) -*/ + * Releaser that only releases the data. + * @param key Key of the database entry + * @param data Data of the database entry + * @param which What is being requested to be released + * @protected + * @see #DBData + * @see #DBRelease + * @see #DBReleaser + * @see #db_default_release(DBType,DBOptions) + */ static void db_release_data(DBKey key, DBData data, DBRelease which) { (void)key;//not used @@ -1059,17 +1059,17 @@ static void db_release_data(DBKey key, DBData data, DBRelease which) } /** -* Releaser that releases both key and data. -* @param key Key of the database entry -* @param data Data of the database entry -* @param which What is being requested to be released -* @protected -* @see #DBKey -* @see #DBData -* @see #DBRelease -* @see #DBReleaser -* @see #db_default_release(DBType,DBOptions) -*/ + * Releaser that releases both key and data. + * @param key Key of the database entry + * @param data Data of the database entry + * @param which What is being requested to be released + * @protected + * @see #DBKey + * @see #DBData + * @see #DBRelease + * @see #DBReleaser + * @see #db_default_release(DBType,DBOptions) + */ static void db_release_both(DBKey key, DBData data, DBRelease which) { DB_COUNTSTAT(db_release_both); @@ -1078,52 +1078,52 @@ static void db_release_both(DBKey key, DBData data, DBRelease which) } /*****************************************************************************\ -* (4) Section with protected functions used in the interface of the * -* database and interface of the iterator. * -* dbit_obj_first - Fetches the first entry from the database. * -* dbit_obj_last - Fetches the last entry from the database. * -* dbit_obj_next - Fetches the next entry from the database. * -* dbit_obj_prev - Fetches the previous entry from the database. * -* dbit_obj_exists - Returns true if the current entry exists. * -* dbit_obj_remove - Remove the current entry from the database. * -* dbit_obj_destroy - Destroys the iterator, unlocking the database and * -* freeing used memory. * -* db_obj_iterator - Return a new database iterator. * -* db_obj_exists - Checks if an entry exists. * -* db_obj_get - Get the data identified by the key. * -* db_obj_vgetall - Get the data of the matched entries. * -* db_obj_getall - Get the data of the matched entries. * -* db_obj_vensure - Get the data identified by the key, creating if it * -* doesn't exist yet. * -* db_obj_ensure - Get the data identified by the key, creating if it * -* doesn't exist yet. * -* db_obj_put - Put data identified by the key in the database. * -* db_obj_remove - Remove an entry from the database. * -* db_obj_vforeach - Apply a function to every entry in the database. * -* db_obj_foreach - Apply a function to every entry in the database. * -* db_obj_vclear - Remove all entries from the database. * -* db_obj_clear - Remove all entries from the database. * -* db_obj_vdestroy - Destroy the database, freeing all the used memory. * -* db_obj_destroy - Destroy the database, freeing all the used memory. * -* db_obj_size - Return the size of the database. * -* db_obj_type - Return the type of the database. * -* db_obj_options - Return the options of the database. * + * (4) Section with protected functions used in the interface of the * + * database and interface of the iterator. * + * dbit_obj_first - Fetches the first entry from the database. * + * dbit_obj_last - Fetches the last entry from the database. * + * dbit_obj_next - Fetches the next entry from the database. * + * dbit_obj_prev - Fetches the previous entry from the database. * + * dbit_obj_exists - Returns true if the current entry exists. * + * dbit_obj_remove - Remove the current entry from the database. * + * dbit_obj_destroy - Destroys the iterator, unlocking the database and * + * freeing used memory. * + * db_obj_iterator - Return a new database iterator. * + * db_obj_exists - Checks if an entry exists. * + * db_obj_get - Get the data identified by the key. * + * db_obj_vgetall - Get the data of the matched entries. * + * db_obj_getall - Get the data of the matched entries. * + * db_obj_vensure - Get the data identified by the key, creating if it * + * doesn't exist yet. * + * db_obj_ensure - Get the data identified by the key, creating if it * + * doesn't exist yet. * + * db_obj_put - Put data identified by the key in the database. * + * db_obj_remove - Remove an entry from the database. * + * db_obj_vforeach - Apply a function to every entry in the database. * + * db_obj_foreach - Apply a function to every entry in the database. * + * db_obj_vclear - Remove all entries from the database. * + * db_obj_clear - Remove all entries from the database. * + * db_obj_vdestroy - Destroy the database, freeing all the used memory. * + * db_obj_destroy - Destroy the database, freeing all the used memory. * + * db_obj_size - Return the size of the database. * + * db_obj_type - Return the type of the database. * + * db_obj_options - Return the options of the database. * \*****************************************************************************/ /** -* Fetches the first entry in the database. -* Returns the data of the entry. -* Puts the key in out_key, if out_key is not NULL. -* @param self Iterator -* @param out_key Key of the entry -* @return Data of the entry -* @protected -* @see DBIterator#first -*/ + * Fetches the first entry in the database. + * Returns the data of the entry. + * Puts the key in out_key, if out_key is not NULL. + * @param self Iterator + * @param out_key Key of the entry + * @return Data of the entry + * @protected + * @see DBIterator#first + */ DBData* dbit_obj_first(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; - + DB_COUNTSTAT(dbit_first); // position before the first entry it->ht_index = -1; @@ -1133,19 +1133,19 @@ DBData* dbit_obj_first(DBIterator* self, DBKey* out_key) } /** -* Fetches the last entry in the database. -* Returns the data of the entry. -* Puts the key in out_key, if out_key is not NULL. -* @param self Iterator -* @param out_key Key of the entry -* @return Data of the entry -* @protected -* @see DBIterator#last -*/ + * Fetches the last entry in the database. + * Returns the data of the entry. + * Puts the key in out_key, if out_key is not NULL. + * @param self Iterator + * @param out_key Key of the entry + * @return Data of the entry + * @protected + * @see DBIterator#last + */ DBData* dbit_obj_last(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; - + DB_COUNTSTAT(dbit_last); // position after the last entry it->ht_index = HASH_SIZE; @@ -1155,15 +1155,15 @@ DBData* dbit_obj_last(DBIterator* self, DBKey* out_key) } /** -* Fetches the next entry in the database. -* Returns the data of the entry. -* Puts the key in out_key, if out_key is not NULL. -* @param self Iterator -* @param out_key Key of the entry -* @return Data of the entry -* @protected -* @see DBIterator#next -*/ + * Fetches the next entry in the database. + * Returns the data of the entry. + * Puts the key in out_key, if out_key is not NULL. + * @param self Iterator + * @param out_key Key of the entry + * @return Data of the entry + * @protected + * @see DBIterator#next + */ DBData* dbit_obj_next(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1231,15 +1231,15 @@ DBData* dbit_obj_next(DBIterator* self, DBKey* out_key) } /** -* Fetches the previous entry in the database. -* Returns the data of the entry. -* Puts the key in out_key, if out_key is not NULL. -* @param self Iterator -* @param out_key Key of the entry -* @return Data of the entry -* @protected -* @see DBIterator#prev -*/ + * Fetches the previous entry in the database. + * Returns the data of the entry. + * Puts the key in out_key, if out_key is not NULL. + * @param self Iterator + * @param out_key Key of the entry + * @return Data of the entry + * @protected + * @see DBIterator#prev + */ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1267,7 +1267,7 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) node = &fake; } - + while( node ) {// next node if( node->left ) @@ -1308,14 +1308,14 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) } /** -* Returns true if the fetched entry exists. -* The databases entries might have NULL data, so use this to to test if -* the iterator is done. -* @param self Iterator -* @return true if the entry exists -* @protected -* @see DBIterator#exists -*/ + * Returns true if the fetched entry exists. + * The databases entries might have NULL data, so use this to to test if + * the iterator is done. + * @param self Iterator + * @return true if the entry exists + * @protected + * @see DBIterator#exists + */ bool dbit_obj_exists(DBIterator* self) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1325,17 +1325,17 @@ bool dbit_obj_exists(DBIterator* self) } /** -* Removes the current entry from the database. -* NOTE: {@link DBIterator#exists} will return false until another entry -* is fetched -* Puts data of the removed entry in out_data, if out_data is not NULL. -* @param self Iterator -* @param out_data Data of the removed entry. -* @return 1 if entry was removed, 0 otherwise -* @protected -* @see DBMap#remove -* @see DBIterator#remove -*/ + * Removes the current entry from the database. + * NOTE: {@link DBIterator#exists} will return false until another entry + * is fetched + * Puts data of the removed entry in out_data, if out_data is not NULL. + * @param self Iterator + * @param out_data Data of the removed entry. + * @return 1 if entry was removed, 0 otherwise + * @protected + * @see DBMap#remove + * @see DBIterator#remove + */ int dbit_obj_remove(DBIterator* self, DBData *out_data) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1359,10 +1359,10 @@ int dbit_obj_remove(DBIterator* self, DBData *out_data) } /** -* Destroys this iterator and unlocks the database. -* @param self Iterator -* @protected -*/ + * Destroys this iterator and unlocks the database. + * @param self Iterator + * @protected + */ void dbit_obj_destroy(DBIterator* self) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1375,14 +1375,14 @@ void dbit_obj_destroy(DBIterator* self) } /** -* Returns a new iterator for this database. -* The iterator keeps the database locked until it is destroyed. -* The database will keep functioning normally but will only free internal -* memory when unlocked, so destroy the iterator as soon as possible. -* @param self Database -* @return New iterator -* @protected -*/ + * Returns a new iterator for this database. + * The iterator keeps the database locked until it is destroyed. + * The database will keep functioning normally but will only free internal + * memory when unlocked, so destroy the iterator as soon as possible. + * @param self Database + * @return New iterator + * @protected + */ static DBIterator* db_obj_iterator(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -1408,13 +1408,13 @@ static DBIterator* db_obj_iterator(DBMap* self) } /** -* Returns true if the entry exists. -* @param self Interface of the database -* @param key Key that identifies the entry -* @return true is the entry exists -* @protected -* @see DBMap#exists -*/ + * Returns true if the entry exists. + * @param self Interface of the database + * @param key Key that identifies the entry + * @return true is the entry exists + * @protected + * @see DBMap#exists + */ static bool db_obj_exists(DBMap* self, DBKey key) { DBMap_impl* db = (DBMap_impl*)self; @@ -1459,13 +1459,13 @@ static bool db_obj_exists(DBMap* self, DBKey key) } /** -* Get the data of the entry identified by the key. -* @param self Interface of the database -* @param key Key that identifies the entry -* @return Data of the entry or NULL if not found -* @protected -* @see DBMap#get -*/ + * Get the data of the entry identified by the key. + * @param self Interface of the database + * @param key Key that identifies the entry + * @return Data of the entry or NULL if not found + * @protected + * @see DBMap#get + */ static DBData* db_obj_get(DBMap* self, DBKey key) { DBMap_impl* db = (DBMap_impl*)self; @@ -1511,21 +1511,21 @@ static DBData* db_obj_get(DBMap* self, DBKey key) } /** -* Get the data of the entries matched by <code>match</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. -* Returns the number of entries that matched. -* NOTE: if the value returned is greater than <code>max</code>, only the -* first <code>max</code> entries found are put into the buffer. -* @param self Interface of the database -* @param buf Buffer to put the data of the matched entries -* @param max Maximum number of data entries to be put into buf -* @param match Function that matches the database entries -* @param ... Extra arguments for match -* @return The number of entries that matched -* @protected -* @see DBMap#vgetall -*/ + * Get the data of the entries matched by <code>match</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. + * Returns the number of entries that matched. + * NOTE: if the value returned is greater than <code>max</code>, only the + * first <code>max</code> entries found are put into the buffer. + * @param self Interface of the database + * @param buf Buffer to put the data of the matched entries + * @param max Maximum number of data entries to be put into buf + * @param match Function that matches the database entries + * @param ... Extra arguments for match + * @return The number of entries that matched + * @protected + * @see DBMap#vgetall + */ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1554,17 +1554,17 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, } va_end(argscopy); } - + if (node->left) { node = node->left; continue; } - + if (node->right) { node = node->right; continue; } - + while (node) { parent = node->parent; if (parent && parent->right && parent->left == node) { @@ -1581,23 +1581,23 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, } /** -* Just calls {@link DBMap#vgetall}. -* Get the data of the entries matched by <code>match</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. -* Returns the number of entries that matched. -* NOTE: if the value returned is greater than <code>max</code>, only the -* first <code>max</code> entries found are put into the buffer. -* @param self Interface of the database -* @param buf Buffer to put the data of the matched entries -* @param max Maximum number of data entries to be put into buf -* @param match Function that matches the database entries -* @param ... Extra arguments for match -* @return The number of entries that matched -* @protected -* @see DBMap#vgetall -* @see DBMap#getall -*/ + * Just calls {@link DBMap#vgetall}. + * Get the data of the entries matched by <code>match</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. + * Returns the number of entries that matched. + * NOTE: if the value returned is greater than <code>max</code>, only the + * first <code>max</code> entries found are put into the buffer. + * @param self Interface of the database + * @param buf Buffer to put the data of the matched entries + * @param max Maximum number of data entries to be put into buf + * @param match Function that matches the database entries + * @param ... Extra arguments for match + * @return The number of entries that matched + * @protected + * @see DBMap#vgetall + * @see DBMap#getall + */ static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, ...) { va_list args; @@ -1613,17 +1613,17 @@ static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, D } /** -* 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 -* <code>create</code>. -* @param self Interface of the database -* @param key Key that identifies the entry -* @param create Function used to create the data if the entry doesn't exist -* @param args Extra arguments for create -* @return Data of the entry -* @protected -* @see DBMap#vensure -*/ + * 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 + * <code>create</code>. + * @param self Interface of the database + * @param key Key that identifies the entry + * @param create Function used to create the data if the entry doesn't exist + * @param args Extra arguments for create + * @return Data of the entry + * @protected + * @see DBMap#vensure + */ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1666,9 +1666,9 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li va_list argscopy; if (db->item_count == UINT32_MAX) { ShowError("db_vensure: item_count overflow, aborting item insertion.\n" - "Database allocated at %s:%d", - db->alloc_file, db->alloc_line); - return NULL; + "Database allocated at %s:%d", + db->alloc_file, db->alloc_line); + return NULL; } DB_COUNTSTAT(db_node_alloc); node = ers_alloc(db->nodes, struct dbn); @@ -1711,19 +1711,19 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li } /** -* Just calls {@link DBMap#vensure}. -* 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 -* <code>create</code>. -* @param self Interface of the database -* @param key Key that identifies the entry -* @param create Function used to create the data if the entry doesn't exist -* @param ... Extra arguments for create -* @return Data of the entry -* @protected -* @see DBMap#vensure -* @see DBMap#ensure -*/ + * Just calls {@link DBMap#vensure}. + * 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 + * <code>create</code>. + * @param self Interface of the database + * @param key Key that identifies the entry + * @param create Function used to create the data if the entry doesn't exist + * @param ... Extra arguments for create + * @return Data of the entry + * @protected + * @see DBMap#vensure + * @see DBMap#ensure + */ static DBData* db_obj_ensure(DBMap* self, DBKey key, DBCreateData create, ...) { va_list args; @@ -1739,18 +1739,18 @@ static DBData* db_obj_ensure(DBMap* self, DBKey key, DBCreateData create, ...) } /** -* Put the data identified by the key in the database. -* Puts the previous data in out_data, if out_data is not NULL. -* NOTE: Uses the new key, the old one is released. -* @param self Interface of the database -* @param key Key that identifies the data -* @param data Data to be put in the database -* @param out_data Previous data if the entry exists -* @return 1 if if the entry already exists, 0 otherwise -* @protected -* @see #db_malloc_dbn(void) -* @see DBMap#put -*/ + * Put the data identified by the key in the database. + * Puts the previous data in out_data, if out_data is not NULL. + * NOTE: Uses the new key, the old one is released. + * @param self Interface of the database + * @param key Key that identifies the data + * @param data Data to be put in the database + * @param out_data Previous data if the entry exists + * @return 1 if if the entry already exists, 0 otherwise + * @protected + * @see #db_malloc_dbn(void) + * @see DBMap#put + */ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) { DBMap_impl* db = (DBMap_impl*)self; @@ -1763,8 +1763,8 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_put: Database is being destroyed, aborting entry insertion.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; // nullpo candidate } if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) { @@ -1778,8 +1778,8 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) if (db->item_count == UINT32_MAX) { ShowError("db_put: item_count overflow, aborting item insertion.\n" - "Database allocated at %s:%d", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d", + db->alloc_file, db->alloc_line); return 0; } // search for an equal node @@ -1845,17 +1845,17 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) } /** -* Remove an entry from the database. -* Puts the previous data in out_data, if out_data is not NULL. -* NOTE: The key (of the database) is released in {@link #db_free_add(DBMap_impl*,DBNode,DBNode *)}. -* @param self Interface of the database -* @param key Key that identifies the entry -* @param out_data Previous data if the entry exists -* @return 1 if if the entry already exists, 0 otherwise -* @protected -* @see #db_free_add(DBMap_impl*,DBNode,DBNode *) -* @see DBMap#remove -*/ + * Remove an entry from the database. + * Puts the previous data in out_data, if out_data is not NULL. + * NOTE: The key (of the database) is released in {@link #db_free_add(DBMap_impl*,DBNode,DBNode *)}. + * @param self Interface of the database + * @param key Key that identifies the entry + * @param out_data Previous data if the entry exists + * @return 1 if if the entry already exists, 0 otherwise + * @protected + * @see #db_free_add(DBMap_impl*,DBNode,DBNode *) + * @see DBMap#remove + */ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) { DBMap_impl* db = (DBMap_impl*)self; @@ -1867,8 +1867,8 @@ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_remove: Database is being destroyed. Aborting entry deletion.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; // nullpo candidate } if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) { @@ -1902,15 +1902,15 @@ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) } /** -* Apply <code>func</code> to every entry in the database. -* Returns the sum of values returned by func. -* @param self Interface of the database -* @param func Function to be applied -* @param args Extra arguments for func -* @return Sum of the values returned by func -* @protected -* @see DBMap#vforeach -*/ + * Apply <code>func</code> to every entry in the database. + * Returns the sum of values returned by func. + * @param self Interface of the database + * @param func Function to be applied + * @param args Extra arguments for func + * @return Sum of the values returned by func + * @protected + * @see DBMap#vforeach + */ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1960,17 +1960,17 @@ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args) } /** -* Just calls {@link DBMap#vforeach}. -* Apply <code>func</code> to every entry in the database. -* Returns the sum of values returned by func. -* @param self Interface of the database -* @param func Function to be applyed -* @param ... Extra arguments for func -* @return Sum of the values returned by func -* @protected -* @see DBMap#vforeach -* @see DBMap#foreach -*/ + * Just calls {@link DBMap#vforeach}. + * Apply <code>func</code> to every entry in the database. + * Returns the sum of values returned by func. + * @param self Interface of the database + * @param func Function to be applyed + * @param ... Extra arguments for func + * @return Sum of the values returned by func + * @protected + * @see DBMap#vforeach + * @see DBMap#foreach + */ static int db_obj_foreach(DBMap* self, DBApply func, ...) { va_list args; @@ -1986,17 +1986,17 @@ static int db_obj_foreach(DBMap* self, DBApply func, ...) } /** -* Removes all entries from the database. -* Before deleting an entry, func is applied to it. -* Releases the key and the data. -* Returns the sum of values returned by func, if it exists. -* @param self Interface of the database -* @param func Function to be applied to every entry before deleting -* @param args Extra arguments for func -* @return Sum of values returned by func -* @protected -* @see DBMap#vclear -*/ + * Removes all entries from the database. + * Before deleting an entry, func is applied to it. + * Releases the key and the data. + * Returns the sum of values returned by func, if it exists. + * @param self Interface of the database + * @param func Function to be applied to every entry before deleting + * @param args Extra arguments for func + * @return Sum of values returned by func + * @protected + * @see DBMap#vclear + */ static int db_obj_vclear(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -2056,21 +2056,21 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args) } /** -* Just calls {@link DBMap#vclear}. -* Removes all entries from the database. -* Before deleting an entry, func is applied to it. -* Releases the key and the data. -* Returns the sum of values returned by func, if it exists. -* 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). -* @param self Interface of the database -* @param func Function to be applied to every entry before deleting -* @param ... Extra arguments for func -* @return Sum of values returned by func -* @protected -* @see DBMap#vclear -* @see DBMap#clear -*/ + * Just calls {@link DBMap#vclear}. + * Removes all entries from the database. + * Before deleting an entry, func is applied to it. + * Releases the key and the data. + * Returns the sum of values returned by func, if it exists. + * 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). + * @param self Interface of the database + * @param func Function to be applied to every entry before deleting + * @param ... Extra arguments for func + * @return Sum of values returned by func + * @protected + * @see DBMap#vclear + * @see DBMap#clear + */ static int db_obj_clear(DBMap* self, DBApply func, ...) { va_list args; @@ -2086,18 +2086,18 @@ static int db_obj_clear(DBMap* self, DBApply func, ...) } /** -* Finalize the database, feeing all the memory it uses. -* Before deleting an entry, func is applied to it. -* Returns the sum of values returned by func, if it exists. -* 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). -* @param self Interface of the database -* @param func Function to be applied to every entry before deleting -* @param args Extra arguments for func -* @return Sum of values returned by func -* @protected -* @see DBMap#vdestroy -*/ + * Finalize the database, feeing all the memory it uses. + * Before deleting an entry, func is applied to it. + * Returns the sum of values returned by func, if it exists. + * 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). + * @param self Interface of the database + * @param func Function to be applied to every entry before deleting + * @param args Extra arguments for func + * @return Sum of values returned by func + * @protected + * @see DBMap#vdestroy + */ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -2107,21 +2107,21 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_vdestroy: Database is already locked for destruction. Aborting second database destruction.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; } if (db->free_lock) ShowWarning("db_vdestroy: Database is still in use, %u lock(s) left. Continuing database destruction.\n" - "Database allocated at %s:%d\n", - db->free_lock, db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->free_lock, db->alloc_file, db->alloc_line); #ifdef DB_ENABLE_STATS switch (db->type) { - case DB_INT: DB_COUNTSTAT(db_int_destroy); break; - case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break; - case DB_STRING: DB_COUNTSTAT(db_string_destroy); break; - case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break; + case DB_INT: DB_COUNTSTAT(db_int_destroy); break; + case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break; + case DB_STRING: DB_COUNTSTAT(db_string_destroy); break; + case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break; } #endif /* DB_ENABLE_STATS */ db_free_lock(db); @@ -2137,21 +2137,21 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) } /** -* Just calls {@link DBMap#db_vdestroy}. -* Finalize the database, feeing all the memory it uses. -* Before deleting an entry, func is applied to it. -* Releases the key and the data. -* Returns the sum of values returned by func, if it exists. -* NOTE: This locks the database globally. Any attempt to insert or remove -* a database entry will give an error and be aborted. -* @param self Database -* @param func Function to be applied to every entry before deleting -* @param ... Extra arguments for func -* @return Sum of values returned by func -* @protected -* @see DBMap#vdestroy -* @see DBMap#destroy -*/ + * Just calls {@link DBMap#db_vdestroy}. + * Finalize the database, feeing all the memory it uses. + * Before deleting an entry, func is applied to it. + * Releases the key and the data. + * Returns the sum of values returned by func, if it exists. + * NOTE: This locks the database globally. Any attempt to insert or remove + * a database entry will give an error and be aborted. + * @param self Database + * @param func Function to be applied to every entry before deleting + * @param ... Extra arguments for func + * @return Sum of values returned by func + * @protected + * @see DBMap#vdestroy + * @see DBMap#destroy + */ static int db_obj_destroy(DBMap* self, DBApply func, ...) { va_list args; @@ -2167,13 +2167,13 @@ static int db_obj_destroy(DBMap* self, DBApply func, ...) } /** -* Return the size of the database (number of items in the database). -* @param self Interface of the database -* @return Size of the database -* @protected -* @see DBMap_impl#item_count -* @see DBMap#size -*/ + * Return the size of the database (number of items in the database). + * @param self Interface of the database + * @return Size of the database + * @protected + * @see DBMap_impl#item_count + * @see DBMap#size + */ static unsigned int db_obj_size(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2190,13 +2190,13 @@ static unsigned int db_obj_size(DBMap* self) } /** -* Return the type of database. -* @param self Interface of the database -* @return Type of the database -* @protected -* @see DBMap_impl#type -* @see DBMap#type -*/ + * Return the type of database. + * @param self Interface of the database + * @return Type of the database + * @protected + * @see DBMap_impl#type + * @see DBMap#type + */ static DBType db_obj_type(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2213,13 +2213,13 @@ static DBType db_obj_type(DBMap* self) } /** -* Return the options of the database. -* @param self Interface of the database -* @return Options of the database -* @protected -* @see DBMap_impl#options -* @see DBMap#options -*/ + * Return the options of the database. + * @param self Interface of the database + * @return Options of the database + * @protected + * @see DBMap_impl#options + * @see DBMap#options + */ static DBOptions db_obj_options(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2236,121 +2236,120 @@ static DBOptions db_obj_options(DBMap* self) } /*****************************************************************************\ -* (5) Section with public functions. -* db_fix_options - Apply database type restrictions to the options. -* 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_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_alloc - Allocate a new database. -* db_i2key - Manual cast from 'int' to 'DBKey'. -* db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. -* db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. -* db_i2data - Manual cast from 'int' to 'DBData'. -* db_ui2data - Manual cast from 'unsigned int' to 'DBData'. -* db_ptr2data - Manual cast from 'void*' to 'DBData'. -* db_data2i - Gets 'int' value from 'DBData'. -* db_data2ui - Gets 'unsigned int' value from 'DBData'. -* db_data2ptr - Gets 'void*' value from 'DBData'. -* db_init - Initializes the database system. -* db_final - Finalizes the database system. + * (5) Section with public functions. + * db_fix_options - Apply database type restrictions to the options. + * 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_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_alloc - Allocate a new database. + * db_i2key - Manual cast from 'int' to 'DBKey'. + * db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. + * db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. + * db_i2data - Manual cast from 'int' to 'DBData'. + * db_ui2data - Manual cast from 'unsigned int' to 'DBData'. + * db_ptr2data - Manual cast from 'void*' to 'DBData'. + * db_data2i - Gets 'int' value from 'DBData'. + * db_data2ui - Gets 'unsigned int' value from 'DBData'. + * db_data2ptr - Gets 'void*' value from 'DBData'. + * db_init - Initializes the database system. + * db_final - Finalizes the database system. \*****************************************************************************/ /** -* Returns the fixed options according to the database type. -* Sets required options and unsets unsupported options. -* For numeric databases DB_OPT_DUP_KEY and DB_OPT_RELEASE_KEY are unset. -* @param type Type of the database -* @param options Original options of the database -* @return Fixed options of the database -* @private -* @see #db_default_release(DBType,DBOptions) -* @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short) -*/ + * Returns the fixed options according to the database type. + * Sets required options and unsets unsupported options. + * For numeric databases DB_OPT_DUP_KEY and DB_OPT_RELEASE_KEY are unset. + * @param type Type of the database + * @param options Original options of the database + * @return Fixed options of the database + * @private + * @see #db_default_release(DBType,DBOptions) + * @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short) + */ DBOptions db_fix_options(DBType type, DBOptions options) { DB_COUNTSTAT(db_fix_options); switch (type) { - case DB_INT: - case DB_UINT: // Numeric database, do nothing with the keys - return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)); - - default: - ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options); - case DB_STRING: - case DB_ISTRING: // String databases, no fix required - return options; + case DB_INT: + case DB_UINT: // Numeric database, do nothing with the keys + return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)); + + default: + ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options); + case DB_STRING: + case DB_ISTRING: // String databases, no fix required + return options; } } - /** -* Returns the default comparator for the specified type of database. -* @param type Type of database -* @return Comparator for the type of database or NULL if unknown database -* @public -* @see #db_int_cmp(DBKey,DBKey,unsigned short) -* @see #db_uint_cmp(DBKey,DBKey,unsigned short) -* @see #db_string_cmp(DBKey,DBKey,unsigned short) -* @see #db_istring_cmp(DBKey,DBKey,unsigned short) -*/ + * Returns the default comparator for the specified type of database. + * @param type Type of database + * @return Comparator for the type of database or NULL if unknown database + * @public + * @see #db_int_cmp(DBKey,DBKey,unsigned short) + * @see #db_uint_cmp(DBKey,DBKey,unsigned short) + * @see #db_string_cmp(DBKey,DBKey,unsigned short) + * @see #db_istring_cmp(DBKey,DBKey,unsigned short) + */ DBComparator db_default_cmp(DBType type) { DB_COUNTSTAT(db_default_cmp); switch (type) { - case DB_INT: return &db_int_cmp; - case DB_UINT: return &db_uint_cmp; - case DB_STRING: return &db_string_cmp; - case DB_ISTRING: return &db_istring_cmp; - default: - ShowError("db_default_cmp: Unknown database type %u\n", type); - return NULL; + case DB_INT: return &db_int_cmp; + case DB_UINT: return &db_uint_cmp; + case DB_STRING: return &db_string_cmp; + case DB_ISTRING: return &db_istring_cmp; + default: + ShowError("db_default_cmp: Unknown database type %u\n", type); + return NULL; } } /** -* Returns the default hasher for the specified type of database. -* @param type Type of database -* @return Hasher of the type of database or NULL if unknown database -* @public -* @see #db_int_hash(DBKey,unsigned short) -* @see #db_uint_hash(DBKey,unsigned short) -* @see #db_string_hash(DBKey,unsigned short) -* @see #db_istring_hash(DBKey,unsigned short) -*/ + * Returns the default hasher for the specified type of database. + * @param type Type of database + * @return Hasher of the type of database or NULL if unknown database + * @public + * @see #db_int_hash(DBKey,unsigned short) + * @see #db_uint_hash(DBKey,unsigned short) + * @see #db_string_hash(DBKey,unsigned short) + * @see #db_istring_hash(DBKey,unsigned short) + */ DBHasher db_default_hash(DBType type) { DB_COUNTSTAT(db_default_hash); switch (type) { - case DB_INT: return &db_int_hash; - case DB_UINT: return &db_uint_hash; - case DB_STRING: return &db_string_hash; - case DB_ISTRING: return &db_istring_hash; - default: - ShowError("db_default_hash: Unknown database type %u\n", type); - return NULL; + case DB_INT: return &db_int_hash; + case DB_UINT: return &db_uint_hash; + case DB_STRING: return &db_string_hash; + case DB_ISTRING: return &db_istring_hash; + default: + ShowError("db_default_hash: Unknown database type %u\n", type); + return NULL; } } /** -* Returns the default releaser for the specified type of database with the -* specified options. -* NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)} -* before choosing the releaser. -* @param type Type of database -* @param options Options of the database -* @return Default releaser for the type of database with the specified options -* @public -* @see #db_release_nothing(DBKey,DBData,DBRelease) -* @see #db_release_key(DBKey,DBData,DBRelease) -* @see #db_release_data(DBKey,DBData,DBRelease) -* @see #db_release_both(DBKey,DBData,DBRelease) -* @see #db_custom_release(DBRelease) -*/ + * Returns the default releaser for the specified type of database with the + * specified options. + * NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)} + * before choosing the releaser. + * @param type Type of database + * @param options Options of the database + * @return Default releaser for the type of database with the specified options + * @public + * @see #db_release_nothing(DBKey,DBData,DBRelease) + * @see #db_release_key(DBKey,DBData,DBRelease) + * @see #db_release_data(DBKey,DBData,DBRelease) + * @see #db_release_both(DBKey,DBData,DBRelease) + * @see #db_custom_release(DBRelease) + */ DBReleaser db_default_release(DBType type, DBOptions options) { DB_COUNTSTAT(db_default_release); - options = DB->fix_options(type, options); + options = iDB->fix_options(type, options); if (options&DB_OPT_RELEASE_DATA) { // Release data, what about the key? if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)) return &db_release_both; // Release both key and data @@ -2362,62 +2361,62 @@ DBReleaser db_default_release(DBType type, DBOptions options) } /** -* Returns the releaser that releases the specified release options. -* @param which Options that specified what the releaser releases -* @return Releaser for the specified release options -* @public -* @see #db_release_nothing(DBKey,DBData,DBRelease) -* @see #db_release_key(DBKey,DBData,DBRelease) -* @see #db_release_data(DBKey,DBData,DBRelease) -* @see #db_release_both(DBKey,DBData,DBRelease) -* @see #db_default_release(DBType,DBOptions) -*/ + * Returns the releaser that releases the specified release options. + * @param which Options that specified what the releaser releases + * @return Releaser for the specified release options + * @public + * @see #db_release_nothing(DBKey,DBData,DBRelease) + * @see #db_release_key(DBKey,DBData,DBRelease) + * @see #db_release_data(DBKey,DBData,DBRelease) + * @see #db_release_both(DBKey,DBData,DBRelease) + * @see #db_default_release(DBType,DBOptions) + */ DBReleaser db_custom_release(DBRelease which) { DB_COUNTSTAT(db_custom_release); switch (which) { - case DB_RELEASE_NOTHING: return &db_release_nothing; - case DB_RELEASE_KEY: return &db_release_key; - case DB_RELEASE_DATA: return &db_release_data; - case DB_RELEASE_BOTH: return &db_release_both; - default: - ShowError("db_custom_release: Unknown release options %u\n", which); - return NULL; + case DB_RELEASE_NOTHING: return &db_release_nothing; + case DB_RELEASE_KEY: return &db_release_key; + case DB_RELEASE_DATA: return &db_release_data; + case DB_RELEASE_BOTH: return &db_release_both; + default: + ShowError("db_custom_release: Unknown release options %u\n", which); + return NULL; } } /** -* Allocate a new database of the specified type. -* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)} -* before creating the database. -* @param file 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 options Options of the database -* @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). -* @return The interface of the database -* @public -* @see #DBMap_impl -* @see #db_fix_options(DBType,DBOptions) -*/ -DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen) -{ + * Allocate a new database of the specified type. + * NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)} + * before creating the database. + * @param file 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 options Options of the database + * @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). + * @return The interface of the database + * @public + * @see #DBMap_impl + * @see #db_fix_options(DBType,DBOptions) + */ +DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOptions options, unsigned short maxlen) { DBMap_impl* db; unsigned int i; + char ers_name[50]; #ifdef DB_ENABLE_STATS DB_COUNTSTAT(db_alloc); switch (type) { - case DB_INT: DB_COUNTSTAT(db_int_alloc); break; - case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break; - case DB_STRING: DB_COUNTSTAT(db_string_alloc); break; - case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; + case DB_INT: DB_COUNTSTAT(db_int_alloc); break; + case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break; + case DB_STRING: DB_COUNTSTAT(db_string_alloc); break; + case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; } #endif /* DB_ENABLE_STATS */ db = ers_alloc(db_alloc_ers, struct DBMap_impl); - options = DB->fix_options(type, options); + options = iDB->fix_options(type, options); /* Interface of the database */ db->vtable.iterator = db_obj_iterator; db->vtable.exists = db_obj_exists; @@ -2446,10 +2445,11 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi db->free_max = 0; db->free_lock = 0; /* Other */ - db->nodes = ers_new(sizeof(struct dbn),"db.c::db_alloc",ERS_OPT_NONE); - db->cmp = DB->default_cmp(type); - db->hash = DB->default_hash(type); - db->release = DB->default_release(type, options); + snprintf(ers_name, 50, "db_alloc:nodes:%s:%s:%d",func,file,line); + db->nodes = ers_new(sizeof(struct dbn),ers_name,ERS_OPT_WAIT|ERS_OPT_FREE_NAME); + db->cmp = iDB->default_cmp(type); + db->hash = iDB->default_hash(type); + db->release = iDB->default_release(type, options); for (i = 0; i < HASH_SIZE; i++) db->ht[i] = NULL; db->cache = NULL; @@ -2466,11 +2466,11 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi } /** -* Manual cast from 'int' to the union DBKey. -* @param key Key to be casted -* @return The key as a DBKey union -* @public -*/ + * Manual cast from 'int' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ DBKey db_i2key(int key) { DBKey ret; @@ -2481,11 +2481,11 @@ DBKey db_i2key(int key) } /** -* Manual cast from 'unsigned int' to the union DBKey. -* @param key Key to be casted -* @return The key as a DBKey union -* @public -*/ + * Manual cast from 'unsigned int' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ DBKey db_ui2key(unsigned int key) { DBKey ret; @@ -2496,11 +2496,11 @@ DBKey db_ui2key(unsigned int key) } /** -* Manual cast from 'const char *' to the union DBKey. -* @param key Key to be casted -* @return The key as a DBKey union -* @public -*/ + * Manual cast from 'const char *' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ DBKey db_str2key(const char *key) { DBKey ret; @@ -2511,11 +2511,11 @@ DBKey db_str2key(const char *key) } /** -* Manual cast from 'int' to the struct DBData. -* @param data Data to be casted -* @return The data as a DBData struct -* @public -*/ + * Manual cast from 'int' to the struct DBData. + * @param data Data to be casted + * @return The data as a DBData struct + * @public + */ DBData db_i2data(int data) { DBData ret; @@ -2527,11 +2527,11 @@ DBData db_i2data(int data) } /** -* Manual cast from 'unsigned int' to the struct DBData. -* @param data Data to be casted -* @return The data as a DBData struct -* @public -*/ + * Manual cast from 'unsigned int' to the struct DBData. + * @param data Data to be casted + * @return The data as a DBData struct + * @public + */ DBData db_ui2data(unsigned int data) { DBData ret; @@ -2543,11 +2543,11 @@ DBData db_ui2data(unsigned int data) } /** -* Manual cast from 'void *' to the struct DBData. -* @param data Data to be casted -* @return The data as a DBData struct -* @public -*/ + * Manual cast from 'void *' to the struct DBData. + * @param data Data to be casted + * @return The data as a DBData struct + * @public + */ DBData db_ptr2data(void *data) { DBData ret; @@ -2559,12 +2559,12 @@ DBData db_ptr2data(void *data) } /** -* Gets int type data from struct DBData. -* If data is not int type, returns 0. -* @param data Data -* @return Integer value of the data. -* @public -*/ + * Gets int type data from struct DBData. + * If data is not int type, returns 0. + * @param data Data + * @return Integer value of the data. + * @public + */ int db_data2i(DBData *data) { DB_COUNTSTAT(db_data2i); @@ -2574,12 +2574,12 @@ int db_data2i(DBData *data) } /** -* Gets unsigned int type data from struct DBData. -* If data is not unsigned int type, returns 0. -* @param data Data -* @return Unsigned int value of the data. -* @public -*/ + * Gets unsigned int type data from struct DBData. + * If data is not unsigned int type, returns 0. + * @param data Data + * @return Unsigned int value of the data. + * @public + */ unsigned int db_data2ui(DBData *data) { DB_COUNTSTAT(db_data2ui); @@ -2589,12 +2589,12 @@ unsigned int db_data2ui(DBData *data) } /** -* Gets void* type data from struct DBData. -* If data is not void* type, returns NULL. -* @param data Data -* @return Void* value of the data. -* @public -*/ + * Gets void* type data from struct DBData. + * If data is not void* type, returns NULL. + * @param data Data + * @return Void* value of the data. + * @public + */ void* db_data2ptr(DBData *data) { DB_COUNTSTAT(db_data2ptr); @@ -2604,10 +2604,10 @@ void* db_data2ptr(DBData *data) } /** -* Initializes the database system. -* @public -* @see #db_final(void) -*/ + * Initializes the database system. + * @public + * @see #db_final(void) + */ void db_init(void) { db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_NONE); db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_NONE); @@ -2615,93 +2615,93 @@ void db_init(void) { } /** -* Finalizes the database system. -* @public -* @see #db_init(void) -*/ + * Finalizes the database system. + * @public + * @see #db_init(void) + */ void db_final(void) { #ifdef DB_ENABLE_STATS DB_COUNTSTAT(db_final); ShowInfo(CL_WHITE"Database nodes"CL_RESET":\n" - "allocated %u, freed %u\n", - stats.db_node_alloc, stats.db_node_free); + "allocated %u, freed %u\n", + stats.db_node_alloc, stats.db_node_free); ShowInfo(CL_WHITE"Database types"CL_RESET":\n" - "DB_INT : allocated %10u, destroyed %10u\n" - "DB_UINT : allocated %10u, destroyed %10u\n" - "DB_STRING : allocated %10u, destroyed %10u\n" - "DB_ISTRING : allocated %10u, destroyed %10u\n", - stats.db_int_alloc, stats.db_int_destroy, - stats.db_uint_alloc, stats.db_uint_destroy, - stats.db_string_alloc, stats.db_string_destroy, - stats.db_istring_alloc, stats.db_istring_destroy); + "DB_INT : allocated %10u, destroyed %10u\n" + "DB_UINT : allocated %10u, destroyed %10u\n" + "DB_STRING : allocated %10u, destroyed %10u\n" + "DB_ISTRING : allocated %10u, destroyed %10u\n", + stats.db_int_alloc, stats.db_int_destroy, + stats.db_uint_alloc, stats.db_uint_destroy, + stats.db_string_alloc, stats.db_string_destroy, + stats.db_istring_alloc, stats.db_istring_destroy); ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n" - "db_rotate_left %10u, db_rotate_right %10u,\n" - "db_rebalance %10u, db_rebalance_erase %10u,\n" - "db_is_key_null %10u,\n" - "db_dup_key %10u, db_dup_key_free %10u,\n" - "db_free_add %10u, db_free_remove %10u,\n" - "db_free_lock %10u, db_free_unlock %10u,\n" - "db_int_cmp %10u, db_uint_cmp %10u,\n" - "db_string_cmp %10u, db_istring_cmp %10u,\n" - "db_int_hash %10u, db_uint_hash %10u,\n" - "db_string_hash %10u, db_istring_hash %10u,\n" - "db_release_nothing %10u, db_release_key %10u,\n" - "db_release_data %10u, db_release_both %10u,\n" - "dbit_first %10u, dbit_last %10u,\n" - "dbit_next %10u, dbit_prev %10u,\n" - "dbit_exists %10u, dbit_remove %10u,\n" - "dbit_destroy %10u, db_iterator %10u,\n" - "db_exits %10u, db_get %10u,\n" - "db_getall %10u, db_vgetall %10u,\n" - "db_ensure %10u, db_vensure %10u,\n" - "db_put %10u, db_remove %10u,\n" - "db_foreach %10u, db_vforeach %10u,\n" - "db_clear %10u, db_vclear %10u,\n" - "db_destroy %10u, db_vdestroy %10u,\n" - "db_size %10u, db_type %10u,\n" - "db_options %10u, db_fix_options %10u,\n" - "db_default_cmp %10u, db_default_hash %10u,\n" - "db_default_release %10u, db_custom_release %10u,\n" - "db_alloc %10u, db_i2key %10u,\n" - "db_ui2key %10u, db_str2key %10u,\n" - "db_i2data %10u, db_ui2data %10u,\n" - "db_ptr2data %10u, db_data2i %10u,\n" - "db_data2ui %10u, db_data2ptr %10u,\n" - "db_init %10u, db_final %10u\n", - stats.db_rotate_left, stats.db_rotate_right, - stats.db_rebalance, stats.db_rebalance_erase, - stats.db_is_key_null, - stats.db_dup_key, stats.db_dup_key_free, - stats.db_free_add, stats.db_free_remove, - stats.db_free_lock, stats.db_free_unlock, - stats.db_int_cmp, stats.db_uint_cmp, - stats.db_string_cmp, stats.db_istring_cmp, - stats.db_int_hash, stats.db_uint_hash, - stats.db_string_hash, stats.db_istring_hash, - stats.db_release_nothing, stats.db_release_key, - stats.db_release_data, stats.db_release_both, - stats.dbit_first, stats.dbit_last, - stats.dbit_next, stats.dbit_prev, - stats.dbit_exists, stats.dbit_remove, - stats.dbit_destroy, stats.db_iterator, - stats.db_exists, stats.db_get, - stats.db_getall, stats.db_vgetall, - stats.db_ensure, stats.db_vensure, - stats.db_put, stats.db_remove, - stats.db_foreach, stats.db_vforeach, - stats.db_clear, stats.db_vclear, - stats.db_destroy, stats.db_vdestroy, - stats.db_size, stats.db_type, - stats.db_options, stats.db_fix_options, - stats.db_default_cmp, stats.db_default_hash, - stats.db_default_release, stats.db_custom_release, - stats.db_alloc, stats.db_i2key, - stats.db_ui2key, stats.db_str2key, - stats.db_i2data, stats.db_ui2data, - stats.db_ptr2data, stats.db_data2i, - stats.db_data2ui, stats.db_data2ptr, - stats.db_init, stats.db_final); + "db_rotate_left %10u, db_rotate_right %10u,\n" + "db_rebalance %10u, db_rebalance_erase %10u,\n" + "db_is_key_null %10u,\n" + "db_dup_key %10u, db_dup_key_free %10u,\n" + "db_free_add %10u, db_free_remove %10u,\n" + "db_free_lock %10u, db_free_unlock %10u,\n" + "db_int_cmp %10u, db_uint_cmp %10u,\n" + "db_string_cmp %10u, db_istring_cmp %10u,\n" + "db_int_hash %10u, db_uint_hash %10u,\n" + "db_string_hash %10u, db_istring_hash %10u,\n" + "db_release_nothing %10u, db_release_key %10u,\n" + "db_release_data %10u, db_release_both %10u,\n" + "dbit_first %10u, dbit_last %10u,\n" + "dbit_next %10u, dbit_prev %10u,\n" + "dbit_exists %10u, dbit_remove %10u,\n" + "dbit_destroy %10u, db_iterator %10u,\n" + "db_exits %10u, db_get %10u,\n" + "db_getall %10u, db_vgetall %10u,\n" + "db_ensure %10u, db_vensure %10u,\n" + "db_put %10u, db_remove %10u,\n" + "db_foreach %10u, db_vforeach %10u,\n" + "db_clear %10u, db_vclear %10u,\n" + "db_destroy %10u, db_vdestroy %10u,\n" + "db_size %10u, db_type %10u,\n" + "db_options %10u, db_fix_options %10u,\n" + "db_default_cmp %10u, db_default_hash %10u,\n" + "db_default_release %10u, db_custom_release %10u,\n" + "db_alloc %10u, db_i2key %10u,\n" + "db_ui2key %10u, db_str2key %10u,\n" + "db_i2data %10u, db_ui2data %10u,\n" + "db_ptr2data %10u, db_data2i %10u,\n" + "db_data2ui %10u, db_data2ptr %10u,\n" + "db_init %10u, db_final %10u\n", + stats.db_rotate_left, stats.db_rotate_right, + stats.db_rebalance, stats.db_rebalance_erase, + stats.db_is_key_null, + stats.db_dup_key, stats.db_dup_key_free, + stats.db_free_add, stats.db_free_remove, + stats.db_free_lock, stats.db_free_unlock, + stats.db_int_cmp, stats.db_uint_cmp, + stats.db_string_cmp, stats.db_istring_cmp, + stats.db_int_hash, stats.db_uint_hash, + stats.db_string_hash, stats.db_istring_hash, + stats.db_release_nothing, stats.db_release_key, + stats.db_release_data, stats.db_release_both, + stats.dbit_first, stats.dbit_last, + stats.dbit_next, stats.dbit_prev, + stats.dbit_exists, stats.dbit_remove, + stats.dbit_destroy, stats.db_iterator, + stats.db_exists, stats.db_get, + stats.db_getall, stats.db_vgetall, + stats.db_ensure, stats.db_vensure, + stats.db_put, stats.db_remove, + stats.db_foreach, stats.db_vforeach, + stats.db_clear, stats.db_vclear, + stats.db_destroy, stats.db_vdestroy, + stats.db_size, stats.db_type, + stats.db_options, stats.db_fix_options, + stats.db_default_cmp, stats.db_default_hash, + stats.db_default_release, stats.db_custom_release, + stats.db_alloc, stats.db_i2key, + stats.db_ui2key, stats.db_str2key, + stats.db_i2data, stats.db_ui2data, + stats.db_ptr2data, stats.db_data2i, + stats.db_data2ui, stats.db_data2ptr, + stats.db_init, stats.db_final); #endif /* DB_ENABLE_STATS */ ers_destroy(db_iterator_ers); ers_destroy(db_alloc_ers); @@ -2829,25 +2829,23 @@ void linkdb_final( struct linkdb_node** head ) } *head = NULL; } - -void db_defaults(void) -{ - DB = &DB_s; - DB->alloc = db_alloc; - DB->custom_release = db_custom_release; - DB->data2i = db_data2i; - DB->data2ptr = db_data2ptr; - DB->data2ui = db_data2ui; - DB->default_cmp = db_default_cmp; - DB->default_hash = db_default_hash; - DB->default_release = db_default_release; - DB->final = db_final; - DB->fix_options = db_fix_options; - DB->i2data = db_i2data; - DB->i2key = db_i2key; - DB->init = db_init; - DB->ptr2data = db_ptr2data; - DB->str2key = db_str2key; - DB->ui2data = db_ui2data; - DB->ui2key = db_ui2key; -}
\ No newline at end of file +void db_defaults(void) { + iDB = &iDB_s; + iDB->alloc = db_alloc; + iDB->custom_release = db_custom_release; + iDB->data2i = db_data2i; + iDB->data2ptr = db_data2ptr; + iDB->data2ui = db_data2ui; + iDB->default_cmp = db_default_cmp; + iDB->default_hash = db_default_hash; + iDB->default_release = db_default_release; + iDB->final = db_final; + iDB->fix_options = db_fix_options; + iDB->i2data = db_i2data; + iDB->i2key = db_i2key; + iDB->init = db_init; + iDB->ptr2data = db_ptr2data; + iDB->str2key = db_str2key; + iDB->ui2data = db_ui2data; + iDB->ui2key = db_ui2key; +} diff --git a/src/common/db.h b/src/common/db.h index f1f6146be..8ad033cce 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -599,73 +599,73 @@ struct DBMap { // For easy access to the common functions. #define db_exists(db,k) ( (db)->exists((db),(k)) ) -#define idb_exists(db,k) ( (db)->exists((db),DB->i2key(k)) ) -#define uidb_exists(db,k) ( (db)->exists((db),DB->ui2key(k)) ) -#define strdb_exists(db,k) ( (db)->exists((db),DB->str2key(k)) ) +#define idb_exists(db,k) ( (db)->exists((db),iDB->i2key(k)) ) +#define uidb_exists(db,k) ( (db)->exists((db),iDB->ui2key(k)) ) +#define strdb_exists(db,k) ( (db)->exists((db),iDB->str2key(k)) ) // Get pointer-type data from DBMaps of various key types -#define db_get(db,k) ( DB->data2ptr((db)->get((db),(k))) ) -#define idb_get(db,k) ( DB->data2ptr((db)->get((db),DB->i2key(k))) ) -#define uidb_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui2key(k))) ) -#define strdb_get(db,k) ( DB->data2ptr((db)->get((db),DB->str2key(k))) ) +#define db_get(db,k) ( iDB->data2ptr((db)->get((db),(k))) ) +#define idb_get(db,k) ( iDB->data2ptr((db)->get((db),iDB->i2key(k))) ) +#define uidb_get(db,k) ( iDB->data2ptr((db)->get((db),iDB->ui2key(k))) ) +#define strdb_get(db,k) ( iDB->data2ptr((db)->get((db),iDB->str2key(k))) ) // Get int-type data from DBMaps of various key types -#define db_iget(db,k) ( DB->data2i((db)->get((db),(k))) ) -#define idb_iget(db,k) ( DB->data2i((db)->get((db),DB->i2key(k))) ) -#define uidb_iget(db,k) ( DB->data2i((db)->get((db),DB->ui2key(k))) ) -#define strdb_iget(db,k) ( DB->data2i((db)->get((db),DB->str2key(k))) ) +#define db_iget(db,k) ( iDB->data2i((db)->get((db),(k))) ) +#define idb_iget(db,k) ( iDB->data2i((db)->get((db),iDB->i2key(k))) ) +#define uidb_iget(db,k) ( iDB->data2i((db)->get((db),iDB->ui2key(k))) ) +#define strdb_iget(db,k) ( iDB->data2i((db)->get((db),iDB->str2key(k))) ) // Get uint-type data from DBMaps of various key types -#define db_uiget(db,k) ( DB->data2ui((db)->get((db),(k))) ) -#define idb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i2key(k))) ) -#define uidb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui2key(k))) ) -#define strdb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->str2key(k))) ) +#define db_uiget(db,k) ( iDB->data2ui((db)->get((db),(k))) ) +#define idb_uiget(db,k) ( iDB->data2ui((db)->get((db),iDB->i2key(k))) ) +#define uidb_uiget(db,k) ( iDB->data2ui((db)->get((db),iDB->ui2key(k))) ) +#define strdb_uiget(db,k) ( iDB->data2ui((db)->get((db),iDB->str2key(k))) ) // Put pointer-type data into DBMaps of various key types -#define db_put(db,k,d) ( (db)->put((db),(k),DB->ptr2data(d),NULL) ) -#define idb_put(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) ) -#define uidb_put(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) ) -#define strdb_put(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) ) +#define db_put(db,k,d) ( (db)->put((db),(k),iDB->ptr2data(d),NULL) ) +#define idb_put(db,k,d) ( (db)->put((db),iDB->i2key(k),iDB->ptr2data(d),NULL) ) +#define uidb_put(db,k,d) ( (db)->put((db),iDB->ui2key(k),iDB->ptr2data(d),NULL) ) +#define strdb_put(db,k,d) ( (db)->put((db),iDB->str2key(k),iDB->ptr2data(d),NULL) ) // Put int-type data into DBMaps of various key types -#define db_iput(db,k,d) ( (db)->put((db),(k),DB->i2data(d),NULL) ) -#define idb_iput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) ) -#define uidb_iput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) ) -#define strdb_iput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) ) +#define db_iput(db,k,d) ( (db)->put((db),(k),iDB->i2data(d),NULL) ) +#define idb_iput(db,k,d) ( (db)->put((db),iDB->i2key(k),iDB->i2data(d),NULL) ) +#define uidb_iput(db,k,d) ( (db)->put((db),iDB->ui2key(k),iDB->i2data(d),NULL) ) +#define strdb_iput(db,k,d) ( (db)->put((db),iDB->str2key(k),iDB->i2data(d),NULL) ) // Put uint-type data into DBMaps of various key types -#define db_uiput(db,k,d) ( (db)->put((db),(k),DB->ui2data(d),NULL) ) -#define idb_uiput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) ) -#define uidb_uiput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) ) -#define strdb_uiput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) ) +#define db_uiput(db,k,d) ( (db)->put((db),(k),iDB->ui2data(d),NULL) ) +#define idb_uiput(db,k,d) ( (db)->put((db),iDB->i2key(k),iDB->ui2data(d),NULL) ) +#define uidb_uiput(db,k,d) ( (db)->put((db),iDB->ui2key(k),iDB->ui2data(d),NULL) ) +#define strdb_uiput(db,k,d) ( (db)->put((db),iDB->str2key(k),iDB->ui2data(d),NULL) ) // Remove entry from DBMaps of various key types #define db_remove(db,k) ( (db)->remove((db),(k),NULL) ) -#define idb_remove(db,k) ( (db)->remove((db),DB->i2key(k),NULL) ) -#define uidb_remove(db,k) ( (db)->remove((db),DB->ui2key(k),NULL) ) -#define strdb_remove(db,k) ( (db)->remove((db),DB->str2key(k),NULL) ) +#define idb_remove(db,k) ( (db)->remove((db),iDB->i2key(k),NULL) ) +#define uidb_remove(db,k) ( (db)->remove((db),iDB->ui2key(k),NULL) ) +#define strdb_remove(db,k) ( (db)->remove((db),iDB->str2key(k),NULL) ) //These are discarding the possible vargs you could send to the function, so those //that require vargs must not use these defines. -#define db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),(k),(f))) ) -#define idb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) ) -#define uidb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) ) -#define strdb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) ) +#define db_ensure(db,k,f) ( iDB->data2ptr((db)->ensure((db),(k),(f))) ) +#define idb_ensure(db,k,f) ( iDB->data2ptr((db)->ensure((db),iDB->i2key(k),(f))) ) +#define uidb_ensure(db,k,f) ( iDB->data2ptr((db)->ensure((db),iDB->ui2key(k),(f))) ) +#define strdb_ensure(db,k,f) ( iDB->data2ptr((db)->ensure((db),iDB->str2key(k),(f))) ) // Database creation and destruction macros -#define idb_alloc(opt) DB->alloc(__FILE__,__LINE__,DB_INT,(opt),sizeof(int)) -#define uidb_alloc(opt) DB->alloc(__FILE__,__LINE__,DB_UINT,(opt),sizeof(unsigned int)) -#define strdb_alloc(opt,maxlen) DB->alloc(__FILE__,__LINE__,DB_STRING,(opt),(maxlen)) -#define stridb_alloc(opt,maxlen) DB->alloc(__FILE__,__LINE__,DB_ISTRING,(opt),(maxlen)) +#define idb_alloc(opt) iDB->alloc(__FILE__,__func__,__LINE__,DB_INT,(opt),sizeof(int)) +#define uidb_alloc(opt) iDB->alloc(__FILE__,__func__,__LINE__,DB_UINT,(opt),sizeof(unsigned int)) +#define strdb_alloc(opt,maxlen) iDB->alloc(__FILE__,__func__,__LINE__,DB_STRING,(opt),(maxlen)) +#define stridb_alloc(opt,maxlen) iDB->alloc(__FILE__,__func__,__LINE__,DB_ISTRING,(opt),(maxlen)) #define db_destroy(db) ( (db)->destroy((db),NULL) ) // Other macros #define db_clear(db) ( (db)->clear(db,NULL) ) #define db_size(db) ( (db)->size(db) ) #define db_iterator(db) ( (db)->iterator(db) ) -#define dbi_first(dbi) ( DB->data2ptr((dbi)->first(dbi,NULL)) ) -#define dbi_last(dbi) ( DB->data2ptr((dbi)->last(dbi,NULL)) ) -#define dbi_next(dbi) ( DB->data2ptr((dbi)->next(dbi,NULL)) ) -#define dbi_prev(dbi) ( DB->data2ptr((dbi)->prev(dbi,NULL)) ) +#define dbi_first(dbi) ( iDB->data2ptr((dbi)->first(dbi,NULL)) ) +#define dbi_last(dbi) ( iDB->data2ptr((dbi)->last(dbi,NULL)) ) +#define dbi_next(dbi) ( iDB->data2ptr((dbi)->next(dbi,NULL)) ) +#define dbi_prev(dbi) ( iDB->data2ptr((dbi)->prev(dbi,NULL)) ) #define dbi_remove(dbi) ( (dbi)->remove(dbi,NULL) ) #define dbi_exists(dbi) ( (dbi)->exists(dbi) ) #define dbi_destroy(dbi) ( (dbi)->destroy(dbi) ) @@ -776,7 +776,7 @@ DBReleaser (*custom_release) (DBRelease which); * @see #db_default_release(DBType,DBOptions) * @see #db_fix_options(DBType,DBOptions) */ -DBMap* (*alloc) (const char *file, int line, DBType type, DBOptions options, unsigned short maxlen); +DBMap* (*alloc) (const char *file, const char *func, int line, DBType type, DBOptions options, unsigned short maxlen); /** * Manual cast from 'int' to the union DBKey. @@ -867,9 +867,9 @@ void (*init) (void); * @see #db_init(void) */ void (*final) (void); -} DB_s; +} iDB_s; -struct db_interface *DB; +struct db_interface *iDB; void db_defaults(void); // Link DB System - From jAthena diff --git a/src/common/des.c b/src/common/des.c index 917fc33e0..ed6d098dc 100644 --- a/src/common/des.c +++ b/src/common/des.c @@ -78,8 +78,8 @@ static void E(BIT64* src) { BIT64 tmp = {{0}}; -if( false ) -{// original +#if 0 + // original static const uint8_t expand_table[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, @@ -98,9 +98,8 @@ if( false ) if( src->b[j / 8 + 4] & mask[j % 8] ) tmp .b[i / 6 + 0] |= mask[i % 6]; } -} -else -{// optimized +#endif + // optimized tmp.b[0] = ((src->b[7]<<5) | (src->b[4]>>3)) & 0x3f; // ..0 vutsr tmp.b[1] = ((src->b[4]<<1) | (src->b[5]>>7)) & 0x3f; // ..srqpo n tmp.b[2] = ((src->b[4]<<5) | (src->b[5]>>3)) & 0x3f; // ..o nmlkj @@ -109,7 +108,6 @@ else tmp.b[5] = ((src->b[6]<<1) | (src->b[7]>>7)) & 0x3f; // ..cba98 7 tmp.b[6] = ((src->b[6]<<5) | (src->b[7]>>3)) & 0x3f; // ..8 76543 tmp.b[7] = ((src->b[7]<<1) | (src->b[4]>>7)) & 0x3f; // ..43210 v -} *src = tmp; } diff --git a/src/common/ers.c b/src/common/ers.c index 13e54b393..69b7609d6 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -50,11 +50,14 @@ #define ERS_BLOCK_ENTRIES 2048 + struct ers_list { struct ers_list *Next; }; +struct ers_instance_t; + typedef struct ers_cache { // Allocated object size, including ers_list size @@ -75,21 +78,23 @@ typedef struct ers_cache // Free objects count unsigned int Free; - // Used objects count + // Used blocks count unsigned int Used; - + + // Objects in-use count + unsigned int UsedObjs; + // Linked list struct ers_cache *Next, *Prev; } ers_cache_t; -typedef struct -{ +struct ers_instance_t { // Interface to ERS struct eri VTable; // Name, used for debbuging purpouses char *Name; - + // Misc options enum ERSOptions Options; @@ -98,11 +103,21 @@ typedef struct // Count of objects in use, used for detecting memory leaks unsigned int Count; -} ers_instance_t; + +#ifdef DEBUG + /* for data analysis [Ind/Hercules] */ + unsigned int Peak; + struct ers_instance_t *Next, *Prev; +#endif + +}; // Array containing a pointer for all ers_cache structures -static ers_cache_t *CacheList; +static ers_cache_t *CacheList = NULL; +#ifdef DEBUG + static struct ers_instance_t *InstanceList = NULL; +#endif static ers_cache_t *ers_find_cache(unsigned int size) { @@ -119,6 +134,7 @@ static ers_cache_t *ers_find_cache(unsigned int size) cache->Blocks = NULL; cache->Free = 0; cache->Used = 0; + cache->UsedObjs = 0; cache->Max = 0; if (CacheList == NULL) @@ -157,7 +173,7 @@ static void ers_free_cache(ers_cache_t *cache, bool remove) static void *ers_obj_alloc_entry(ERS self) { - ers_instance_t *instance = (ers_instance_t *)self; + struct ers_instance_t *instance = (struct ers_instance_t *)self; void *ret; if (instance == NULL) @@ -192,13 +208,19 @@ static void *ers_obj_alloc_entry(ERS self) } instance->Count++; + instance->Cache->UsedObjs++; + +#ifdef DEBUG + if( instance->Count > instance->Peak ) + instance->Peak = instance->Count; +#endif return ret; } static void ers_obj_free_entry(ERS self, void *entry) { - ers_instance_t *instance = (ers_instance_t *)self; + struct ers_instance_t *instance = (struct ers_instance_t *)self; struct ers_list *reuse = (struct ers_list *)((unsigned char *)entry - sizeof(struct ers_list)); if (instance == NULL) @@ -215,11 +237,12 @@ static void ers_obj_free_entry(ERS self, void *entry) reuse->Next = instance->Cache->ReuseList; instance->Cache->ReuseList = reuse; instance->Count--; + instance->Cache->UsedObjs--; } static size_t ers_obj_entry_size(ERS self) { - ers_instance_t *instance = (ers_instance_t *)self; + struct ers_instance_t *instance = (struct ers_instance_t *)self; if (instance == NULL) { @@ -232,7 +255,7 @@ static size_t ers_obj_entry_size(ERS self) static void ers_obj_destroy(ERS self) { - ers_instance_t *instance = (ers_instance_t *)self; + struct ers_instance_t *instance = (struct ers_instance_t *)self; if (instance == NULL) { @@ -247,13 +270,26 @@ static void ers_obj_destroy(ERS self) if (--instance->Cache->ReferenceCount <= 0) ers_free_cache(instance->Cache, true); +#ifdef DEBUG + if (instance->Next) + instance->Next->Prev = instance->Prev; + + if (instance->Prev) + instance->Prev->Next = instance->Next; + else + InstanceList = instance->Next; +#endif + + if( instance->Options & ERS_OPT_FREE_NAME ) + aFree(instance->Name); + aFree(instance); } ERS ers_new(uint32 size, char *name, enum ERSOptions options) { - ers_instance_t *instance; - CREATE(instance, ers_instance_t, 1); + struct ers_instance_t *instance; + CREATE(instance,struct ers_instance_t, 1); size += sizeof(struct ers_list); if (size % ERS_ALIGNED) @@ -264,29 +300,66 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options) instance->VTable.entry_size = ers_obj_entry_size; instance->VTable.destroy = ers_obj_destroy; - instance->Name = name; + instance->Name = ( options & ERS_OPT_FREE_NAME ) ? aStrdup(name) : name; instance->Options = options; instance->Cache = ers_find_cache(size); instance->Cache->ReferenceCount++; +#ifdef DEBUG + if (InstanceList == NULL) { + InstanceList = instance; + } else { + instance->Next = InstanceList; + instance->Next->Prev = instance; + InstanceList = instance; + InstanceList->Prev = NULL; + } +#endif instance->Count = 0; return &instance->VTable; } -void ers_report(void) -{ +void ers_report(void) { ers_cache_t *cache; - int i = 0; + unsigned int cache_c = 0, blocks_u = 0, blocks_a = 0, memory_b = 0, memory_t = 0; +#ifdef DEBUG + struct ers_instance_t *instance; + unsigned int instance_c = 0, instance_c_d = 0; + + for (instance = InstanceList; instance; instance = instance->Next) { + instance_c++; + if( (instance->Options & ERS_OPT_WAIT) && !instance->Count ) + continue; + instance_c_d++; + ShowMessage(CL_BOLD"[ERS Instance "CL_NORMAL""CL_WHITE"%s"CL_NORMAL""CL_BOLD" report]\n"CL_NORMAL, instance->Name); + ShowMessage("\tblock size : %u\n", instance->Cache->ObjectSize); + ShowMessage("\tblocks being used : %u\n", instance->Count); + ShowMessage("\tpeak blocks : %u\n", instance->Peak); + ShowMessage("\tmemory in use : %.2f MB\n", instance->Count == 0 ? 0. : (double)((instance->Count * instance->Cache->ObjectSize)/1024)/1024); + } +#endif + for (cache = CacheList; cache; cache = cache->Next) { - ShowMessage(CL_BOLD"[Entry manager #%u report]\n"CL_NORMAL, ++i); + cache_c++; + ShowMessage(CL_BOLD"[ERS Cache of size '"CL_NORMAL""CL_WHITE"%u"CL_NORMAL""CL_BOLD"' report]\n"CL_NORMAL, cache->ObjectSize); ShowMessage("\tinstances : %u\n", cache->ReferenceCount); - ShowMessage("\tblock array size : %u\n", cache->ObjectSize); - ShowMessage("\tallocated blocks : %u\n", cache->Free+cache->Used); - ShowMessage("\tentries being used : %u\n", cache->Used); - ShowMessage("\tunused entries : %u\n", cache->Free); + ShowMessage("\tblocks in use : %u/%u\n", cache->UsedObjs, cache->UsedObjs+cache->Free); + ShowMessage("\tblocks unused : %u\n", cache->Free); + ShowMessage("\tmemory in use : %.2f MB\n", cache->UsedObjs == 0 ? 0. : (double)((cache->UsedObjs * cache->ObjectSize)/1024)/1024); + ShowMessage("\tmemory allocated : %.2f MB\n", (cache->Free+cache->UsedObjs) == 0 ? 0. : (double)(((cache->UsedObjs+cache->Free) * cache->ObjectSize)/1024)/1024); + blocks_u += cache->UsedObjs; + blocks_a += cache->UsedObjs + cache->Free; + memory_b += cache->UsedObjs * cache->ObjectSize; + memory_t += (cache->UsedObjs+cache->Free) * cache->ObjectSize; } +#ifdef DEBUG + ShowInfo("ers_report: '"CL_WHITE"%u"CL_NORMAL"' instances in use, '"CL_WHITE"%u"CL_NORMAL"' displayed\n",instance_c,instance_c_d); +#endif + ShowInfo("ers_report: '"CL_WHITE"%u"CL_NORMAL"' caches in use\n",cache_c); + ShowInfo("ers_report: '"CL_WHITE"%u"CL_NORMAL"' blocks in use, consuming '"CL_WHITE"%.2f MB"CL_NORMAL"'\n",blocks_u,(double)((memory_b)/1024)/1024); + ShowInfo("ers_report: '"CL_WHITE"%u"CL_NORMAL"' blocks total, consuming '"CL_WHITE"%.2f MB"CL_NORMAL"' \n",blocks_a,(double)((memory_t)/1024)/1024); } void ers_force_destroy_all(void) diff --git a/src/common/ers.h b/src/common/ers.h index dc66af5ef..4871d8d50 100644 --- a/src/common/ers.h +++ b/src/common/ers.h @@ -71,8 +71,10 @@ #endif /* not ERS_ALIGN_ENTRY */ enum ERSOptions { - ERS_OPT_NONE = 0, - ERS_OPT_CLEAR = 1,/* silently clears any entries left in the manager upon destruction */ + ERS_OPT_NONE = 0x0, + ERS_OPT_CLEAR = 0x1,/* silently clears any entries left in the manager upon destruction */ + ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */ + ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */ }; /** diff --git a/src/common/grfio.c b/src/common/grfio.c index bf66dba52..77b976926 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -171,7 +171,7 @@ static void grf_decode_full(unsigned char* buf, size_t len, int cycle) scycle = 7; // so decrypt/de-shuffle periodically - j = -1; // 0, adjusted to fit the ++j step + j = (size_t)-1; // 0, adjusted to fit the ++j step for( i = 20; i < nblocks; ++i ) { if( i % dcycle == 0 ) @@ -408,7 +408,7 @@ void* grfio_reads(const char* fname, int* size) declen = ftell(in); fseek(in,0,SEEK_SET); buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination - if(fread(buf2, 1, declen, in) != declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname); + if(fread(buf2, 1, declen, in) != (size_t)declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname); fclose(in); if( size ) @@ -430,7 +430,7 @@ void* grfio_reads(const char* fname, int* size) int fsize = entry->srclen_aligned; unsigned char *buf = (unsigned char *)aMalloc(fsize); fseek(in, entry->srcpos, 0); - if(fread(buf, 1, fsize, in) != fsize) ShowError("An error occured in fread in grfio_reads, grfname=%s\n",grfname); + if(fread(buf, 1, fsize, in) != (size_t)fsize) ShowError("An error occured in fread in grfio_reads, grfname=%s\n",grfname); fclose(in); buf2 = (unsigned char *)aMalloc(entry->declen+1); // +1 for resnametable zero-termination @@ -526,7 +526,7 @@ static int grfio_entryread(const char* grfname, int gentry) long list_size; list_size = grf_size - ftell(fp); grf_filelist = (unsigned char *) aMalloc(list_size); - if(fread(grf_filelist,1,list_size,fp) != list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); } + if(fread(grf_filelist,1,list_size,fp) != (size_t)list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); } fclose(fp); entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7; @@ -559,7 +559,7 @@ static int grfio_entryread(const char* grfname, int gentry) #ifdef GRFIO_LOCAL aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck #else - aentry.gentry = gentry+1; // With no first time LocalFileCheck + aentry.gentry = (char)(gentry+1); // With no first time LocalFileCheck #endif filelist_modify(&aentry); } @@ -611,13 +611,13 @@ static int grfio_entryread(const char* grfname, int gentry) aentry.srclen_aligned = getlong(grf_filelist+ofs2+4); aentry.declen = getlong(grf_filelist+ofs2+8); aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e; - aentry.type = type; + aentry.type = (char)type; safestrncpy(aentry.fn, fname, sizeof(aentry.fn)); aentry.fnd = NULL; #ifdef GRFIO_LOCAL aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck #else - aentry.gentry = gentry+1; // With no first time LocalFileCheck + aentry.gentry = (char)(gentry+1); // With no first time LocalFileCheck #endif filelist_modify(&aentry); } diff --git a/src/common/malloc.c b/src/common/malloc.c index 4874aa0f4..d629aa63f 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -200,6 +200,8 @@ static struct unit_head_large *unit_head_large_first = NULL; static struct block* block_malloc(unsigned short hash); static void block_free(struct block* p); static size_t memmgr_usage_bytes; +static size_t memmgr_usage_bytes_t; + #define block2unit(p, n) ((struct unit_head*)(&(p)->data[ p->unit_size * (n) ])) #define memmgr_assert(v) do { if(!(v)) { ShowError("Memory manager: assertion '" #v "' failed!\n"); } } while(0) @@ -245,12 +247,13 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) /* At that time, the distinction by assigning NULL to unit_head.block */ if(hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) { struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func); + memmgr_usage_bytes_t += size+sizeof(struct unit_head_large); if(p != NULL) { p->size = size; p->unit_head.block = NULL; p->unit_head.size = 0; p->unit_head.file = file; - p->unit_head.line = line; + p->unit_head.line = (unsigned short)line; p->prev = NULL; if (unit_head_large_first == NULL) p->next = NULL; @@ -324,7 +327,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) head->block = block; head->file = file; - head->line = line; + head->line = (unsigned short)line; head->size = (unsigned short)size; *(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf; return (char *)head + sizeof(struct unit_head) - sizeof(long); @@ -332,7 +335,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) void* _mcalloc(size_t num, size_t size, const char *file, int line, const char *func ) { - void *p = malloclib->malloc(num * size,file,line,func); + void *p = iMalloc->malloc(num * size,file,line,func); memset(p,0,num * size); return p; } @@ -341,7 +344,7 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c { size_t old_size; if(memblock == NULL) { - return malloclib->malloc(size,file,line,func); + return iMalloc->malloc(size,file,line,func); } old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; @@ -353,11 +356,11 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c return memblock; } else { // Size Large - void *p = malloclib->malloc(size,file,line,func); + void *p = iMalloc->malloc(size,file,line,func); if(p != NULL) { memcpy(p,memblock,old_size); } - malloclib->free(memblock,file,line,func); + iMalloc->free(memblock,file,line,func); return p; } } @@ -368,7 +371,7 @@ char* _mstrdup(const char *p, const char *file, int line, const char *func ) return NULL; } else { size_t len = strlen(p); - char *string = (char *)malloclib->malloc(len + 1,file,line,func); + char *string = (char *)iMalloc->malloc(len + 1,file,line,func); memcpy(string,p,len+1); return string; } @@ -401,6 +404,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) head_large->next->prev = head_large->prev; } memmgr_usage_bytes -= head_large->size; + memmgr_usage_bytes_t -= head_large->size + sizeof(struct unit_head_large); #ifdef DEBUG_MEMMGR // set freed memory to 0xfd memset(ptr, 0xfd, head_large->size); @@ -422,7 +426,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) #ifdef DEBUG_MEMMGR memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long) ); head->file = file; - head->line = line; + head->line = (unsigned short)line; #endif memmgr_assert( block->unit_used > 0 ); if(--block->unit_used == 0) { @@ -457,6 +461,7 @@ static struct block* block_malloc(unsigned short hash) } else { /* Newly allocated space for the block */ p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__ ); + memmgr_usage_bytes_t += sizeof(struct block) * (BLOCK_ALLOC); if(p == NULL) { ShowFatalError("Memory manager::block_alloc failed.\n"); exit(EXIT_FAILURE); @@ -621,7 +626,7 @@ static void memmgr_final (void) memmgr_log (buf); #endif /* LOG_MEMMGR */ // get block pointer and free it [celest] - malloclib->free(ptr, ALC_MARK); + iMalloc->free(ptr, ALC_MARK); } } } @@ -650,6 +655,86 @@ static void memmgr_final (void) } #endif /* LOG_MEMMGR */ } +/* [Ind/Hercules] */ +void memmgr_report (int extra) { + struct block *block = block_first; + struct unit_head_large *large = unit_head_large_first; + unsigned int count = 0, size = 0; + int j; + unsigned short msize = 1024; + struct { + const char *file; + unsigned short line; + unsigned int size; + unsigned int count; + } data[100]; + memset(&data, 0, sizeof(data)); + + if( extra != 0 ) + msize = extra; + + while (block) { + if (block->unit_used) { + int i; + for (i = 0; i < block->unit_maxused; i++) { + struct unit_head *head = block2unit(block, i); + if( head->block != NULL && head->size > msize ) { + for( j = 0; j < 100; j++ ) { + if( data[j].file == head->file && data[j].line == head->line ) { + data[j].size += head->size; + data[j].count += 1; + break; + } else if( data[j].size == 0 ) { + data[j].file = head->file; + data[j].line = head->line; + data[j].size = head->size; + data[j].count += 1; + break; + } + } + size += (unsigned int)head->size; + count++; + } + } + } + block = block->block_next; + } + + while(large) { + if( large->size > msize ) { + for( j = 0; j < 100; j++ ) { + if( data[j].file == large->unit_head.file && data[j].line == large->unit_head.line ) { + data[j].size += large->size; + data[j].count += 1; + break; + } else if( data[j].size == 0 ) { + data[j].file = large->unit_head.file; + data[j].line = large->unit_head.line; + data[j].size = large->size; + data[j].count += 1; + break; + } + } + size += (unsigned int)large->size; + count++; + } + large = large->next; + } + for( j = 0; j < 100; j++ ) { + if( data[j].size != 0 ) { + ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); + } + } + ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024); + ShowMessage("[malloc] : internal usage %.2f MB | %.2f MB\n",(double)((memmgr_usage_bytes_t-memmgr_usage_bytes)/1024)/1024,(double)((memmgr_usage_bytes_t)/1024)/1024); + + if( extra ) { + ShowMessage("[malloc] : unit_head_large: %d bytes\n",sizeof(struct unit_head_large)); + ShowMessage("[malloc] : unit_head: %d bytes\n",sizeof(struct unit_head)); + ShowMessage("[malloc] : block: %d bytes\n",sizeof(struct block)); + } + +} static void memmgr_init (void) { @@ -677,8 +762,7 @@ void malloc_memory_check(void) /// Returns true if a pointer is valid. /// The check is best-effort, false positives are possible. -bool malloc_verify_ptr(void* ptr) -{ +bool malloc_verify_ptr(void* ptr) { #ifdef USE_MEMMGR return memmgr_verify(ptr) && MEMORY_VERIFY(ptr); #else @@ -687,8 +771,7 @@ bool malloc_verify_ptr(void* ptr) } -size_t malloc_usage (void) -{ +size_t malloc_usage (void) { #ifdef USE_MEMMGR return memmgr_usage (); #else @@ -696,16 +779,16 @@ size_t malloc_usage (void) #endif } -void malloc_final (void) -{ +void malloc_final (void) { #ifdef USE_MEMMGR memmgr_final (); #endif MEMORY_CHECK(); } -void malloc_init (void) -{ +void malloc_init (void) { + memmgr_usage_bytes_t = 0; + memmgr_usage_bytes = 0; #if defined(DMALLOC) && defined(CYGWIN) // http://dmalloc.com/docs/latest/online/dmalloc_19.html dmalloc_debug_setup(getenv("DMALLOC_OPTIONS")); @@ -720,27 +803,26 @@ void malloc_init (void) #endif } -void malloc_defaults() -{ - malloclib = &malloclib_s; - malloclib->init = malloc_init; - malloclib->final = malloc_final; - malloclib->memory_check = malloc_memory_check; - malloclib->usage = malloc_usage; - malloclib->verify_ptr = malloc_verify_ptr; +void malloc_defaults(void) { + iMalloc = &iMalloc_s; + iMalloc->init = malloc_init; + iMalloc->final = malloc_final; + iMalloc->memory_check = malloc_memory_check; + iMalloc->usage = malloc_usage; + iMalloc->verify_ptr = malloc_verify_ptr; // Athena's built-in Memory Manager #ifdef USE_MEMMGR - malloclib->malloc = _mmalloc; - malloclib->calloc = _mcalloc; - malloclib->realloc = _mrealloc; - malloclib->astrdup = _mstrdup; - malloclib->free = _mfree; + iMalloc->malloc = _mmalloc; + iMalloc->calloc = _mcalloc; + iMalloc->realloc = _mrealloc; + iMalloc->astrdup = _mstrdup; + iMalloc->free = _mfree; #else - malloclib->malloc = aMalloc_; - malloclib->calloc = aCalloc_; - malloclib->realloc = aRealloc_; - malloclib->astrdup = aStrdup_; - malloclib->free = aFree_; + iMalloc->malloc = aMalloc_; + iMalloc->calloc = aCalloc_; + iMalloc->realloc = aRealloc_; + iMalloc->astrdup = aStrdup_; + iMalloc->free = aFree_; #endif } diff --git a/src/common/malloc.h b/src/common/malloc.h index 34a26b56e..834781905 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -30,11 +30,11 @@ #undef LOG_MEMMGR #endif -# define aMalloc(n) malloclib->malloc (n,ALC_MARK) -# define aCalloc(m,n) malloclib->calloc (m,n,ALC_MARK) -# define aRealloc(p,n) malloclib->realloc (p,n,ALC_MARK) -# define aStrdup(p) malloclib->astrdup (p,ALC_MARK) -# define aFree(p) malloclib->free (p,ALC_MARK) +# define aMalloc(n) iMalloc->malloc (n,ALC_MARK) +# define aCalloc(m,n) iMalloc->calloc (m,n,ALC_MARK) +# define aRealloc(p,n) iMalloc->realloc (p,n,ALC_MARK) +# define aStrdup(p) iMalloc->astrdup (p,ALC_MARK) +# define aFree(p) iMalloc->free (p,ALC_MARK) /////////////// Buffer Creation ///////////////// // Full credit for this goes to Shinomori [Ajarn] @@ -78,7 +78,9 @@ struct malloc_interface { size_t (*usage) (void); void (*init) (void); void (*final) (void); -} malloclib_s; +} iMalloc_s; -struct malloc_interface *malloclib; +void memmgr_report (int extra); + +struct malloc_interface *iMalloc; #endif /* _MALLOC_H_ */ diff --git a/src/common/mapindex.c b/src/common/mapindex.c index 4649e299d..83de21b2b 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -148,7 +148,7 @@ void mapindex_init(void) { exit(EXIT_FAILURE); //Server can't really run without this file. } memset (&indexes, 0, sizeof (indexes)); - mapindex_db = strdb_alloc(DB_RELEASE_KEY, MAP_NAME_LENGTH); + mapindex_db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); while(fgets(line, sizeof(line), fp)) { if(line[0] == '/' && line[1] == '/') continue; diff --git a/src/common/mapindex.h b/src/common/mapindex.h index d35d9899c..43953a8e0 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -7,7 +7,7 @@ #include "../common/db.h" -/* when a map index search fails, return results from what map? default:prontera */ +// When a map index search fails, return results from what map? default:prontera #define MAP_DEFAULT "prontera" #define MAP_DEFAULT_X 150 #define MAP_DEFAULT_Y 150 diff --git a/src/common/mmo.h b/src/common/mmo.h index d45dea212..c2fdfe43a 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -51,13 +51,14 @@ #define PACKETVER 20120418 #endif -/// comment following line if your client is NOT ragexeRE (required because of conflicting packets in ragexe vs ragexeRE) +// Comment the following line if your client is NOT ragexeRE (required because of conflicting packets in ragexe vs ragexeRE). #define PACKETVER_RE -//Remove/Comment this line to disable sc_data saving. [Skotlex] +// Comment the following line to disable sc_data saving. [Skotlex] #define ENABLE_SC_SAVING -//Remove/Comment this line to disable server-side hot-key saving support [Skotlex] -//Note that newer clients no longer save hotkeys in the registry! + +// Comment the following like to disable server-side hot-key saving support. [Skotlex] +// Note that newer clients no longer save hotkeys in the registry! #define HOTKEY_SAVING #if PACKETVER < 20090603 @@ -71,7 +72,6 @@ #define MAX_HOTKEYS 38 #endif -#define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps #define MAX_INVENTORY 100 //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. #define MAX_CHARS 9 @@ -84,10 +84,10 @@ #define MAX_FAME 1000000000 #define MAX_CART 100 #define MAX_SKILL 1477 -#define MAX_SKILL_ID 10015 //[Ind/Hercules] max used skill id -#define GLOBAL_REG_NUM 256 // max permanent character variables per char -#define ACCOUNT_REG_NUM 64 // max permanent local account variables per account -#define ACCOUNT_REG2_NUM 16 // max permanent global account variables per account +#define MAX_SKILL_ID 10015 // [Ind/Hercules] max used skill ID +#define GLOBAL_REG_NUM 256 // Max permanent character variables per char +#define ACCOUNT_REG_NUM 64 // Max permanent local account variables per account +#define ACCOUNT_REG2_NUM 16 // Max permanent global account variables per account //Should hold the max of GLOBAL/ACCOUNT/ACCOUNT2 (needed for some arrays that hold all three) #define MAX_REG_NUM 256 #define DEFAULT_WALK_SPEED 150 @@ -96,16 +96,16 @@ #define MAX_STORAGE 600 #define MAX_GUILD_STORAGE 600 #define MAX_PARTY 12 -#define MAX_GUILD 16+10*6 // increased max guild members +6 per 1 extension levels [Lupus] -#define MAX_GUILDPOSITION 20 // increased max guild positions to accomodate for all members [Valaris] (removed) [PoW] +#define MAX_GUILD 16+10*6 // Increased max guild members +6 per 1 extension levels [Lupus] +#define MAX_GUILDPOSITION 20 // Increased max guild positions to accomodate for all members [Valaris] (removed) [PoW] #define MAX_GUILDEXPULSION 32 #define MAX_GUILDALLIANCE 16 -#define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan] +#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] #define MAX_GUILDLEVEL 50 -#define MAX_GUARDIANS 8 //Local max per castle. [Skotlex] -#define MAX_QUEST_DB 2400 //Max quests that the server will load -#define MAX_QUEST_OBJECTIVES 3 //Max quest objectives for a quest -#define MAX_START_ITEMS 32 //Max number of items allowed to be given to a char whenever it's created. [mkbu95] +#define MAX_GUARDIANS 8 // Local max per castle. [Skotlex] +#define MAX_QUEST_DB 2410 // Max quests that the server will load +#define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest +#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] // for produce #define MIN_ATTRIBUTE 0 @@ -124,43 +124,43 @@ #define NAME_LENGTH (23 + 1) //For item names, which tend to have much longer names. #define ITEM_NAME_LENGTH 50 -//For Map Names, which the client considers to be 16 in length including the .gat extension +//For Map Names, which the client considers to be 16 in length including the .gat extension. #define MAP_NAME_LENGTH (11 + 1) #define MAP_NAME_LENGTH_EXT (MAP_NAME_LENGTH + 4) #define MAX_FRIENDS 40 #define MAX_MEMOPOINTS 3 -//Size of the fame list arrays. +// Size of the fame list arrays. #define MAX_FAME_LIST 10 -//Limits to avoid ID collision with other game objects +// Limits to avoid ID collision with other game objects #define START_ACCOUNT_NUM 2000000 #define END_ACCOUNT_NUM 100000000 #define START_CHAR_NUM 150000 -//Guilds +// Guilds #define MAX_GUILDMES1 60 #define MAX_GUILDMES2 120 -//Base Homun skill. +// Base Homun skill. #define HM_SKILLBASE 8001 #define MAX_HOMUNSKILL 43 -#define MAX_HOMUNCULUS_CLASS 52 //[orn], Increased to 60 from 16 to allow new Homun-S. +#define MAX_HOMUNCULUS_CLASS 52 // [orn] Increased to 60 from 16 to allow new Homun-S. #define HM_CLASS_BASE 6001 #define HM_CLASS_MAX (HM_CLASS_BASE+MAX_HOMUNCULUS_CLASS-1) -//Mail System +// Mail System #define MAIL_MAX_INBOX 30 #define MAIL_TITLE_LENGTH 40 #define MAIL_BODY_LENGTH 200 -//Mercenary System +// Mercenary System #define MC_SKILLBASE 8201 #define MAX_MERCSKILL 40 #define MAX_MERCENARY_CLASS 61 -//Elemental System +// Elemental System #define MAX_ELEMENTALSKILL 42 #define EL_SKILLBASE 8401 #define MAX_ELESKILLTREE 3 @@ -186,7 +186,7 @@ enum item_types { }; -//Questlog system [Kevin] [Inkfish] +// Questlog system [Kevin] [Inkfish] typedef enum quest_state { Q_INACTIVE, Q_ACTIVE, Q_COMPLETE } quest_state; struct quest { @@ -200,7 +200,7 @@ struct item { int id; short nameid; short amount; - unsigned short equip; // location(s) where item is equipped (using enum equip_pos for bitmasking) + unsigned short equip; // Location(s) where item is equipped (using enum equip_pos for bitmasking). char identify; char refine; char attribute; @@ -220,8 +220,8 @@ enum e_skill_flag SKILL_FLAG_PERMANENT, SKILL_FLAG_TEMPORARY, SKILL_FLAG_PLAGIARIZED, - SKILL_FLAG_REPLACED_LV_0, // temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0', - SKILL_FLAG_PERM_GRANTED, // permanent, granted through someway e.g. script + SKILL_FLAG_REPLACED_LV_0, // Temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0', + SKILL_FLAG_PERM_GRANTED, // Permanent, granted through someway (e.g. script). //... }; @@ -234,7 +234,7 @@ enum e_mmo_charstatus_opt { struct s_skill { unsigned short id; unsigned char lv; - unsigned char flag; // see enum e_skill_flag + unsigned char flag; // See enum e_skill_flag }; struct global_reg { @@ -242,14 +242,14 @@ struct global_reg { char value[256]; }; -//Holds array of global registries, used by the char server and converter. +// Holds array of global registries, used by the char server and converter. struct accreg { int account_id, char_id; int reg_num; struct global_reg reg[MAX_REG_NUM]; }; -//For saving status changes across sessions. [Skotlex] +// For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type long val1, val2, val3, val4, tick; //Remaining duration. @@ -526,6 +526,10 @@ struct guild { /* TODO: still used for something?|: */ unsigned short save_flag; // for TXT saving + + unsigned short *instance; + unsigned short instances; + void *channel; }; diff --git a/src/common/mutex.c b/src/common/mutex.c index 6b4f55119..6bb1efdab 100644 --- a/src/common/mutex.c +++ b/src/common/mutex.c @@ -201,7 +201,7 @@ void racond_wait( racond c, ramutex m, sysint timeout_ticks){ pthread_cond_wait( &c->hCond, &m->hMutex ); }else{ struct timespec wtime; - int64 exact_timeout = gettick() + timeout_ticks; + int64 exact_timeout = iTimer->gettick() + timeout_ticks; wtime.tv_sec = exact_timeout/1000; wtime.tv_nsec = (exact_timeout%1000)*1000000; diff --git a/src/common/random.c b/src/common/random.c index 5c048c7eb..a7d432e34 100644 --- a/src/common/random.c +++ b/src/common/random.c @@ -17,7 +17,7 @@ /// Initializes the random number generator with an appropriate seed. void rnd_init(void) { - uint32 seed = gettick(); + uint32 seed = iTimer->gettick(); seed += (uint32)time(NULL); #if defined(WIN32) seed += GetCurrentProcessId(); diff --git a/src/common/socket.c b/src/common/socket.c index 5126d231b..15b20b16f 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -280,9 +280,10 @@ void set_nonblocking(int fd, unsigned long yes) ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg()); } -void setsocketopts(int fd) -{ +void setsocketopts(int fd, struct hSockOpt *opt) { int yes = 1; // reuse fix + struct linger lopt; + #if !defined(WIN32) // set SO_REAUSEADDR to true, unix only. on windows this option causes // the previous owner of the socket to give up, which is not desirable @@ -297,15 +298,22 @@ void setsocketopts(int fd) // The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway. sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)); + if( opt && opt->setTimeo ) { + struct timeval timeout; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); + sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)); + } + // force the socket into no-wait, graceful-close mode (should be the default, but better make sure) //(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/closesocket_2.asp) - { - struct linger opt; - opt.l_onoff = 0; // SO_DONTLINGER - opt.l_linger = 0; // Do not care - if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&opt, sizeof(opt)) ) + lopt.l_onoff = 0; // SO_DONTLINGER + lopt.l_linger = 0; // Do not care + if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lopt, sizeof(lopt)) ) ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd); - } } /*====================================== @@ -404,8 +412,7 @@ void flush_fifos(void) /*====================================== * CORE : Connection functions *--------------------------------------*/ -int connect_client(int listen_fd) -{ +int connect_client(int listen_fd) { int fd; struct sockaddr_in client_address; socklen_t len; @@ -417,20 +424,18 @@ int connect_client(int listen_fd) ShowError("connect_client: accept failed (%s)!\n", error_msg()); return -1; } - if( fd == 0 ) - {// reserved + if( fd == 0 ) { // reserved ShowError("connect_client: Socket #0 is reserved - Please report this!!!\n"); sClose(fd); return -1; } - if( fd >= FD_SETSIZE ) - {// socket number too big + if( fd >= FD_SETSIZE ) { // socket number too big ShowError("connect_client: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE); sClose(fd); return -1; } - setsocketopts(fd); + setsocketopts(fd,NULL); set_nonblocking(fd, 1); #ifndef MINICORE @@ -457,25 +462,22 @@ int make_listen_bind(uint32 ip, uint16 port) fd = sSocket(AF_INET, SOCK_STREAM, 0); - if( fd == -1 ) - { + if( fd == -1 ) { ShowError("make_listen_bind: socket creation failed (%s)!\n", error_msg()); exit(EXIT_FAILURE); } - if( fd == 0 ) - {// reserved + if( fd == 0 ) { // reserved ShowError("make_listen_bind: Socket #0 is reserved - Please report this!!!\n"); sClose(fd); return -1; } - if( fd >= FD_SETSIZE ) - {// socket number too big + if( fd >= FD_SETSIZE ) { // socket number too big ShowError("make_listen_bind: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE); sClose(fd); return -1; } - setsocketopts(fd); + setsocketopts(fd,NULL); set_nonblocking(fd, 1); server_address.sin_family = AF_INET; @@ -503,7 +505,7 @@ int make_listen_bind(uint32 ip, uint16 port) return fd; } -int make_connection(uint32 ip, uint16 port, bool silent) { +int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { struct sockaddr_in remote_address; int fd; int result; @@ -514,31 +516,29 @@ int make_connection(uint32 ip, uint16 port, bool silent) { ShowError("make_connection: socket creation failed (%s)!\n", error_msg()); return -1; } - if( fd == 0 ) - {// reserved + if( fd == 0 ) {// reserved ShowError("make_connection: Socket #0 is reserved - Please report this!!!\n"); sClose(fd); return -1; } - if( fd >= FD_SETSIZE ) - {// socket number too big + if( fd >= FD_SETSIZE ) {// socket number too big ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE); sClose(fd); return -1; } - setsocketopts(fd); + setsocketopts(fd,opt); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); - if( !silent ) + if( !( opt && opt->silent ) ) ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { - if( !silent ) + if( !( opt && opt->silent ) ) ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg()); do_close(fd); return -1; @@ -947,9 +947,9 @@ static int connect_check_(uint32 ip) if( hist->ddos ) {// flagged as DDoS return (connect_ok == 2 ? 1 : 0); - } else if( DIFF_TICK(gettick(),hist->tick) < ddos_interval ) + } else if( DIFF_TICK(iTimer->gettick(),hist->tick) < ddos_interval ) {// connection within ddos_interval - hist->tick = gettick(); + hist->tick = iTimer->gettick(); if( hist->count++ >= ddos_count ) {// DDoS attack detected hist->ddos = 1; @@ -959,7 +959,7 @@ static int connect_check_(uint32 ip) return connect_ok; } else {// not within ddos_interval, clear data - hist->tick = gettick(); + hist->tick = iTimer->gettick(); hist->count = 0; return connect_ok; } @@ -970,7 +970,7 @@ static int connect_check_(uint32 ip) CREATE(hist, ConnectHistory, 1); memset(hist, 0, sizeof(ConnectHistory)); hist->ip = ip; - hist->tick = gettick(); + hist->tick = iTimer->gettick(); hist->next = connect_history[ip&0xFFFF]; connect_history[ip&0xFFFF] = hist; return connect_ok; @@ -1331,8 +1331,8 @@ void socket_init(void) #ifndef MINICORE // Delete old connection history every 5 minutes memset(connect_history, 0, sizeof(connect_history)); - add_timer_func_list(connect_check_clear, "connect_check_clear"); - add_timer_interval(gettick()+1000, connect_check_clear, 0, 0, 5*60*1000); + iTimer->add_timer_func_list(connect_check_clear, "connect_check_clear"); + iTimer->add_timer_interval(iTimer->gettick()+1000, connect_check_clear, 0, 0, 5*60*1000); #endif ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur); diff --git a/src/common/socket.h b/src/common/socket.h index 4879cb109..b58cbdccf 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _SOCKET_H_ #define _SOCKET_H_ @@ -48,6 +49,9 @@ } \ } while(0) +/* [Ind/Hercules] */ +#define RFIFO2PTR(fd,len) (void*)(session[fd]->rdata + len) + // buffer I/O macros #define RBUFP(p,pos) (((uint8*)(p)) + (pos)) #define RBUFB(p,pos) (*(uint8*)RBUFP((p),(pos))) @@ -94,6 +98,10 @@ struct socket_data void* session_data; // stores application-specific data related to the session }; +struct hSockOpt { + unsigned int silent : 1; + unsigned int setTimeo : 1; +}; // Data prototype declaration @@ -113,7 +121,7 @@ extern bool session_isActive(int fd); // Function prototype declaration int make_listen_bind(uint32 ip, uint16 port); -int make_connection(uint32 ip, uint16 port, bool silent); +int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt); int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size); int realloc_writefifo(int fd, size_t addition); int WFIFOSET(int fd, size_t len); diff --git a/src/common/sql.c b/src/common/sql.c index 391211183..d4bea7c12 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -210,7 +210,7 @@ static int Sql_P_Keepalive(Sql* self) // establish keepalive ping_interval = timeout - 30; // 30-second reserve //add_timer_func_list(Sql_P_KeepaliveTimer, "Sql_P_KeepaliveTimer"); - return add_timer_interval(gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000); + return iTimer->add_timer_interval(iTimer->gettick() + ping_interval*1000, Sql_P_KeepaliveTimer, 0, (intptr_t)self, ping_interval*1000); } @@ -404,7 +404,7 @@ void Sql_Free(Sql* self) { SQL->FreeResult(self); StrBuf->Destroy(&self->buf); - if( self->keepalive != INVALID_TIMER ) delete_timer(self->keepalive, Sql_P_KeepaliveTimer); + if( self->keepalive != INVALID_TIMER ) iTimer->delete_timer(self->keepalive, Sql_P_KeepaliveTimer); aFree(self); } } diff --git a/src/common/timer.c b/src/common/timer.c index edb46bd71..955a971c8 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -257,7 +257,7 @@ int timer_add_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int tid; if( interval < 1 ) { - ShowError("timer_add_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick())); + ShowError("timer_add_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, iTimer->gettick())); return INVALID_TIMER; } @@ -300,7 +300,7 @@ int timer_do_delete(int tid, TimerFunc func) { /// Adjusts a timer's expiration time. /// Returns the new tick value, or -1 if it fails. int timer_addtick(int tid, unsigned int tick) { - return settick_timer(tid, timer_data[tid].tick+tick); + return iTimer->settick_timer(tid, timer_data[tid].tick+tick); } /// Modifies a timer's expiration time (an alternative to deleting a timer and starting a new one). @@ -409,15 +409,26 @@ void timer_final(void) { BHEAP_CLEAR(timer_heap); if (free_timer_list) aFree(free_timer_list); } -void timer_defaults(void) { - gettick = timer_gettick; - gettick_nocache = timer_gettick_nocache; - add_timer = timer_add; - add_timer_interval = timer_add_interval; - add_timer_func_list = timer_add_func_list; - get_timer = timer_get; - delete_timer = timer_do_delete; - addtick_timer = timer_addtick; - settick_timer = timer_settick; - get_uptime = timer_get_uptime; +/*===================================== +* Default Functions : timer.h +* Generated by HerculesInterfaceMaker +* created by Susu +*-------------------------------------*/ +void timer_defaults(void) { + iTimer = &iTimer_s; + + /* funcs */ + iTimer->gettick = timer_gettick; + iTimer->gettick_nocache = timer_gettick_nocache; + iTimer->add_timer = timer_add; + iTimer->add_timer_interval = timer_add_interval; + iTimer->add_timer_func_list = timer_add_func_list; + iTimer->get_timer = timer_get; + iTimer->delete_timer = timer_do_delete; + iTimer->addtick_timer = timer_addtick; + iTimer->settick_timer = timer_settick; + iTimer->get_uptime = timer_get_uptime; + iTimer->do_timer = do_timer; + iTimer->init = timer_init; + iTimer->final = timer_final; } diff --git a/src/common/timer.h b/src/common/timer.h index 902679f51..d68b5ed0f 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -34,27 +34,36 @@ struct TimerData { intptr_t data; }; -// Function prototype declaration +/* Hercules Renewal Phase One */ +/*===================================== +* Interface : timer.h +* Generated by HerculesInterfaceMaker +* created by Susu +*-------------------------------------*/ +struct timer_interface { -int do_timer(unsigned int tick); -void timer_init(void); -void timer_final(void); + /* funcs */ + unsigned int (*gettick) (void); + unsigned int (*gettick_nocache) (void); -/* Hercules Renewal Phase One */ -unsigned int (*gettick) (void); -unsigned int (*gettick_nocache) (void); + int (*add_timer) (unsigned int tick, TimerFunc func, int id, intptr_t data); + int (*add_timer_interval) (unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); + const struct TimerData *(*get_timer) (int tid); + int (*delete_timer) (int tid, TimerFunc func); + + int (*addtick_timer) (int tid, unsigned int tick); + int (*settick_timer) (int tid, unsigned int tick); -int (*add_timer) (unsigned int tick, TimerFunc func, int id, intptr_t data); -int (*add_timer_interval) (unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); -const struct TimerData *(*get_timer) (int tid); -int (*delete_timer) (int tid, TimerFunc func); + int (*add_timer_func_list) (TimerFunc func, char* name); -int (*addtick_timer) (int tid, unsigned int tick); -int (*settick_timer) (int tid, unsigned int tick); + unsigned long (*get_uptime) (void); -int (*add_timer_func_list) (TimerFunc func, char* name); + int (*do_timer) (unsigned int tick); + void (*init) (void); + void (*final) (void); +} iTimer_s; -unsigned long (*get_uptime) (void); +struct timer_interface *iTimer; void timer_defaults(void); |