diff options
author | gepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-03-13 14:46:28 +0000 |
---|---|---|
committer | gepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-03-13 14:46:28 +0000 |
commit | dc5babf8c3fb943a22c440f5afd6957b121926c5 (patch) | |
tree | fcf7000486b4172803ff2929c0b746013d0fb6a9 /src/common/db.h | |
parent | d0932858a07e7df3159003c0b920c50e2e6a1b76 (diff) | |
download | hercules-dc5babf8c3fb943a22c440f5afd6957b121926c5.tar.gz hercules-dc5babf8c3fb943a22c440f5afd6957b121926c5.tar.bz2 hercules-dc5babf8c3fb943a22c440f5afd6957b121926c5.tar.xz hercules-dc5babf8c3fb943a22c440f5afd6957b121926c5.zip |
Enhanced `DBMap` implementation to allow storing integer type data in addition to void pointers.
- Added enum for data: `int`, `unsigned int` and `void*`
- Replaced generic `void*` data with `DBData` struct to hold `int`, `unsigned int` or `void*` (member of `DBNode`)
- Added `db_i2data`, `db_ui2data` and `db_ptr2data` functions to cast from `int`/`uint`/`void*` to `DBData` (used in `DBMap::put()`)
- Added `db_data2i`, `db_data2ui` and `db_data2ptr` functions to get `int`/`uint`/`void*` from `DBData`
- Enabled statistics for new functions in `db_stats` struct
- `DBCreateData` functions (used in `DBMap::ensure()`) now return `DBData` instead of `void*`
- `DBApply` functions (used in `DBMap::foreach()` and `DBMap::destroy()`) now take `DBData*` as a parameter instead of `void*`
- `DBMatcher` functions (used in `DBMap::getall()`) now take `DBData` as a parameter instead of `void*`
- `DBReleaser` functions now take `DBData` as parameter instead of `void*`
- Default releasers release data if it is `void*` (`DB_DATA_PTR`) type
- `DBIterator` functions: `first()`, `last()`, `next()` and `prev()` now return `DBData*` instead of `void*`
- `DBIterator::remove()` now returns `int` (1 if node was found and removed, 0 otherwise) instead of `void*` and takes an extra `DBData*` parameter for the data of removed entry
- `DBMap::get()` and `DBMap::ensure()` now return `DBData*` instead of `void*`
- `DBMap::remove()` and `DBMap::put()` now return `int` (1 if node already existed, 0 otherwise) instead of `void*` and take an extra `DBData*` parameter for the data of removed entry
- `DBMap::put()` now takes `DBData` as parameter instead of `void*`
- `DBMap::getall()` now puts data into `DBData**` buffer instead of `void**` buffer
- Updated macros:
- (`i`/`ui`/`str`)`db_get` and (`i`/`ui`/`str`)`db_ensure` were wrapped with `db_data2ptr` to extract data from `DBData*` that is now returned by `DBMap::get()`
- added (`i`/`ui`/`str`)`db_iget` and (`i`/`ui`/`str`)`db_uiget` that get `DBData` from `DBMap` and extract `int`/`unsigned int` from it (with `db_data2i`/`db_data2ui`)
- `db_put`, `idb_put`, `uidb_put` and `strdb_put` data params were wrapped with `db_ptr2data` to match new signature of `DBMap::put()` (`DBData` instead of `void*`)
- added (`i`/`ui`/`str`)`db_iput` and (`i`/`ui`/`str`)`db_uiput` that put `int`/`unsigned int` into `DBMap` (first wrapping it with `DBData`)
- added `NULL` in place of extra parameter for removed data in `db_remove` macros
- `dbi_first`, `dbi_last`, `dbi_next` and `dbi_prev` were wrapped with `db_data2ptr` to extract data from `DBData*` that is now returned by these `DBIterator` functions
- Updated `DBMap` documentation, and fixed a dozen of typos in it.
- Updated rest of rA code to reflect `DBMap` changes (mostly required signature changes of `DBCreateData` and `DBApply` functions).
- Fixed a bug where `DBMap::put()` would return data of a deleted entry.
- Removed some unnecessary pointer casts.
- Increased `showmsg.c` static buffer size to fit entire DBMap stats report.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15682 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/common/db.h')
-rw-r--r-- | src/common/db.h | 257 |
1 files changed, 190 insertions, 67 deletions
diff --git a/src/common/db.h b/src/common/db.h index e53ace0e6..49a95a135 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -16,12 +16,12 @@ * released. * * * * TODO: * - * - create an enum for the data (with int, unsigned int and void *) * * - create a custom database allocator * * - see what functions need or should be added to the database interface * * * * HISTORY: * - * 2007/11/09 - Added an iterator to the database. + * 2012/03/09 - Added enum for data types (int, uint, void*) * + * 2007/11/09 - Added an iterator to the database. * * 2.1 (Athena build #???#) - Portability fix * * - Fixed the portability of casting to union and added the functions * * {@link DBMap#ensure(DBMap,DBKey,DBCreateData,...)} and * @@ -50,7 +50,9 @@ * DBType - Enumeration of database types. * * DBOptions - Bitfield enumeration of database options. * * DBKey - Union of used key types. * - * DBApply - Format of functions applyed to the databases. * + * DBDataType - Enumeration of data types. * + * DBData - Struct for used data types. * + * DBApply - Format of functions applied to the databases. * * DBMatcher - Format of matchers used in DBMap::getall. * * DBComparator - Format of the comparators used by the databases. * * DBHasher - Format of the hashers used by the databases. * @@ -146,33 +148,65 @@ typedef union DBKey { } DBKey; /** - * Format of funtions that create the data for the key when the entry doesn't + * Supported types of database data. + * @param DB_DATA_INT Uses ints for data. + * @param DB_DATA_UINT Uses unsigned ints for data. + * @param DB_DATA_PTR Uses void pointers for data. + * @public + * @see #DBData + */ +typedef enum DBDataType { + DB_DATA_INT, + DB_DATA_UINT, + DB_DATA_PTR +} DBDataType; + +/** + * Struct for data types used by the database. + * @param type Type of data + * @param u Union of available data types + * @param u.i Data of int type + * @param u.ui Data of unsigned int type + * @param u.ptr Data of void* type + * @public + */ +typedef struct DBData { + DBDataType type; + union { + int i; + unsigned int ui; + void *ptr; + } u; +} DBData; + +/** + * Format of functions that create the data for the key when the entry doesn't * exist in the database yet. * @param key Key of the database entry - * @param args Extra arguments of the funtion + * @param args Extra arguments of the function * @return Data identified by the key to be put in the database * @public * @see DBMap#vensure * @see DBMap#ensure */ -typedef void* (*DBCreateData)(DBKey key, va_list args); +typedef DBData (*DBCreateData)(DBKey key, va_list args); /** - * Format of functions to be applyed to an unspecified quantity of entries of + * Format of functions to be applied to an unspecified quantity of entries of * a database. * Any function that applies this function to the database will return the sum * of values returned by this function. * @param key Key of the database entry * @param data Data of the database entry - * @param args Extra arguments of the funtion - * @return Value to be added up by the funtion that is applying this + * @param args Extra arguments of the function + * @return Value to be added up by the function that is applying this * @public * @see DBMap#vforeach * @see DBMap#foreach * @see DBMap#vdestroy * @see DBMap#destroy */ -typedef int (*DBApply)(DBKey key, void* data, va_list args); +typedef int (*DBApply)(DBKey key, DBData *data, va_list args); /** * Format of functions that match database entries. @@ -185,7 +219,7 @@ typedef int (*DBApply)(DBKey key, void* data, va_list args); * @public * @see DBMap#getall */ -typedef int (*DBMatcher)(DBKey key, void* data, va_list args); +typedef int (*DBMatcher)(DBKey key, DBData data, va_list args); /** * Format of the comparators used internally by the database system. @@ -225,7 +259,7 @@ typedef unsigned int (*DBHasher)(DBKey key, unsigned short maxlen); * @see #db_default_releaser(DBType,DBOptions) * @see #db_custom_release(DBRelease) */ -typedef void (*DBReleaser)(DBKey key, void* data, DBRelease which); +typedef void (*DBReleaser)(DBKey key, DBData data, DBRelease which); @@ -255,7 +289,7 @@ struct DBIterator * @return Data of the entry * @protected */ - void* (*first)(DBIterator* self, DBKey* out_key); + DBData* (*first)(DBIterator* self, DBKey* out_key); /** * Fetches the last entry in the database. @@ -266,7 +300,7 @@ struct DBIterator * @return Data of the entry * @protected */ - void* (*last)(DBIterator* self, DBKey* out_key); + DBData* (*last)(DBIterator* self, DBKey* out_key); /** * Fetches the next entry in the database. @@ -277,7 +311,7 @@ struct DBIterator * @return Data of the entry * @protected */ - void* (*next)(DBIterator* self, DBKey* out_key); + DBData* (*next)(DBIterator* self, DBKey* out_key); /** * Fetches the previous entry in the database. @@ -288,7 +322,7 @@ struct DBIterator * @return Data of the entry * @protected */ - void* (*prev)(DBIterator* self, DBKey* out_key); + DBData* (*prev)(DBIterator* self, DBKey* out_key); /** * Returns true if the fetched entry exists. @@ -303,14 +337,15 @@ struct DBIterator /** * Removes the current entry from the database. * NOTE: {@link DBIterator#exists} will return false until another entry - * is fethed - * Returns the data of the entry. + * is fetched + * Puts data of the removed entry in out_data, if out_data is not NULL. * @param self Iterator - * @return The data of the entry or NULL if not found + * @param out_data Data of the removed entry. + * @return 1 if entry was removed, 0 otherwise * @protected * @see DBMap#remove */ - void* (*remove)(DBIterator* self); + int (*remove)(DBIterator* self, DBData *out_data); /** * Destroys this iterator and unlocks the database. @@ -350,13 +385,13 @@ struct DBMap { bool (*exists)(DBMap* self, DBKey key); /** - * Get the data of the entry identifid by the key. + * Get the data of the entry identified by the key. * @param self Database * @param key Key that identifies the entry * @return Data of the entry or NULL if not found * @protected */ - void* (*get)(DBMap* self, DBKey key); + DBData* (*get)(DBMap* self, DBKey key); /** * Just calls {@link DBMap#vgetall}. @@ -375,7 +410,7 @@ struct DBMap { * @protected * @see DBMap#vgetall(DBMap*,void **,unsigned int,DBMatcher,va_list) */ - unsigned int (*getall)(DBMap* self, void** buf, unsigned int max, DBMatcher match, ...); + unsigned int (*getall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, ...); /** * Get the data of the entries matched by <code>match</code>. @@ -393,7 +428,7 @@ struct DBMap { * @protected * @see DBMap#getall(DBMap*,void **,unsigned int,DBMatcher,...) */ - unsigned int (*vgetall)(DBMap* self, void** buf, unsigned int max, DBMatcher match, va_list args); + unsigned int (*vgetall)(DBMap* self, DBData** buf, unsigned int max, DBMatcher match, va_list args); /** * Just calls {@link DBMap#vensure}. @@ -408,7 +443,7 @@ struct DBMap { * @protected * @see DBMap#vensure(DBMap*,DBKey,DBCreateData,va_list) */ - void* (*ensure)(DBMap* self, DBKey key, DBCreateData create, ...); + DBData* (*ensure)(DBMap* self, DBKey key, DBCreateData create, ...); /** * Get the data of the entry identified by the key. @@ -422,37 +457,39 @@ struct DBMap { * @protected * @see DBMap#ensure(DBMap*,DBKey,DBCreateData,...) */ - void* (*vensure)(DBMap* self, DBKey key, DBCreateData create, va_list args); + DBData* (*vensure)(DBMap* self, DBKey key, DBCreateData create, va_list args); /** * Put the data identified by the key in the database. - * Returns the previous data if the entry exists or NULL. + * 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 Database * @param key Key that identifies the data * @param data Data to be put in the database - * @return The previous data if the entry exists or NULL + * @param out_data Previous data if the entry exists + * @return 1 if if the entry already exists, 0 otherwise * @protected */ - void* (*put)(DBMap* self, DBKey key, void* data); + int (*put)(DBMap* self, DBKey key, DBData data, DBData *out_data); /** * Remove an entry from the database. - * Returns the data of the entry. + * Puts the previous data in out_data, if out_data is not NULL. * NOTE: The key (of the database) is released. * @param self Database * @param key Key that identifies the entry - * @return The data of the entry or NULL if not found + * @param out_data Previous data if the entry exists + * @return 1 if if the entry already exists, 0 otherwise * @protected */ - void* (*remove)(DBMap* self, DBKey key); + int (*remove)(DBMap* self, DBKey key, DBData *out_data); /** * 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 Database - * @param func Function to be applyed + * @param func Function to be applied * @param ... Extra arguments for func * @return Sum of the values returned by func * @protected @@ -464,7 +501,7 @@ struct DBMap { * Apply <code>func</code> to every entry in the database. * Returns the sum of values returned by func. * @param self Database - * @param func Function to be applyed + * @param func Function to be applied * @param args Extra arguments for func * @return Sum of the values returned by func * @protected @@ -475,11 +512,11 @@ struct DBMap { /** * Just calls {@link DBMap#vclear}. * Removes all entries from the database. - * Before deleting an entry, func is applyed to it. + * 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 Database - * @param func Function to be applyed to every entry before deleting + * @param func Function to be applied to every entry before deleting * @param ... Extra arguments for func * @return Sum of values returned by func * @protected @@ -489,11 +526,11 @@ struct DBMap { /** * Removes all entries from the database. - * Before deleting an entry, func is applyed to it. + * 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 Database - * @param func Function to be applyed to every entry before deleting + * @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 @@ -504,13 +541,13 @@ struct DBMap { /** * Just calls {@link DBMap#vdestroy}. * Finalize the database, feeing all the memory it uses. - * Before deleting an entry, func is applyed to it. + * 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 Database - * @param func Function to be applyed to every entry before deleting + * @param func Function to be applied to every entry before deleting * @param ... Extra arguments for func * @return Sum of values returned by func * @protected @@ -520,12 +557,12 @@ struct DBMap { /** * Finalize the database, feeing all the memory it uses. - * Before deleting an entry, func is applyed to it. + * 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 Database - * @param func Function to be applyed to every entry before deleting + * @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 @@ -559,33 +596,61 @@ struct DBMap { }; -//For easy access to the common functions. +// 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 db_get(db,k) ( (db)->get((db),(k)) ) -#define idb_get(db,k) ( (db)->get((db),db_i2key(k)) ) -#define uidb_get(db,k) ( (db)->get((db),db_ui2key(k)) ) -#define strdb_get(db,k) ( (db)->get((db),db_str2key(k)) ) - -#define db_put(db,k,d) ( (db)->put((db),(k),(d)) ) -#define idb_put(db,k,d) ( (db)->put((db),db_i2key(k),(d)) ) -#define uidb_put(db,k,d) ( (db)->put((db),db_ui2key(k),(d)) ) -#define strdb_put(db,k,d) ( (db)->put((db),db_str2key(k),(d)) ) - -#define db_remove(db,k) ( (db)->remove((db),(k)) ) -#define idb_remove(db,k) ( (db)->remove((db),db_i2key(k)) ) -#define uidb_remove(db,k) ( (db)->remove((db),db_ui2key(k)) ) -#define strdb_remove(db,k) ( (db)->remove((db),db_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))) ) + +// 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))) ) + +// 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))) ) + +// 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) ) + +// Put int-type data into DBMaps of various key types +#define db_iput(db,k,d) ( (db)->put((db),(k),db_i2data(d)) ) +#define idb_iput(db,k,d) ( (db)->put((db),db_i2key(k),db_i2data(d)) ) +#define uidb_iput(db,k,d) ( (db)->put((db),db_ui2key(k),db_i2data(d)) ) +#define strdb_iput(db,k,d) ( (db)->put((db),db_str2key(k),db_i2data(d)) ) + +// Put uint-type data into DBMaps of various key types +#define db_uiput(db,k,d) ( (db)->put((db),(k),db_ui2data(d)) ) +#define idb_uiput(db,k,d) ( (db)->put((db),db_i2key(k),db_ui2data(d)) ) +#define uidb_uiput(db,k,d) ( (db)->put((db),db_ui2key(k),db_ui2data(d)) ) +#define strdb_uiput(db,k,d) ( (db)->put((db),db_str2key(k),db_ui2data(d)) ) + +// 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) ) //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)->ensure((db),(k),(f)) ) -#define idb_ensure(db,k,f) ( (db)->ensure((db),db_i2key(k),(f)) ) -#define uidb_ensure(db,k,f) ( (db)->ensure((db),db_ui2key(k),(f)) ) -#define strdb_ensure(db,k,f) ( (db)->ensure((db),db_str2key(k),(f)) ) +#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))) ) // Database creation and destruction macros #define idb_alloc(opt) db_alloc(__FILE__,__LINE__,DB_INT,(opt),sizeof(int)) @@ -597,10 +662,11 @@ struct DBMap { #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) ( (dbi)->first(dbi,NULL) ) -#define dbi_last(dbi) ( (dbi)->last(dbi,NULL) ) -#define dbi_next(dbi) ( (dbi)->next(dbi,NULL) ) -#define dbi_prev(dbi) ( (dbi)->prev(dbi,NULL) ) +#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_remove(dbi) ( (dbi)->remove(dbi,NULL) ) #define dbi_exists(dbi) ( (dbi)->exists(dbi) ) #define dbi_destroy(dbi) ( (dbi)->destroy(dbi) ) @@ -616,8 +682,14 @@ struct DBMap { * 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_init - Initialise the database system. * - * db_final - Finalise the database system. * + * 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. * \*****************************************************************************/ /** @@ -730,6 +802,57 @@ DBKey db_ui2key(unsigned int key); 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 + */ +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 + */ +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 + */ +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 + */ +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 + */ +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 + */ +void* db_data2ptr(DBData *data); + +/** * Initialize the database system. * @public * @see #db_final(void) |