summaryrefslogtreecommitdiff
path: root/src/common/db.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/db.h')
-rw-r--r--src/common/db.h235
1 files changed, 145 insertions, 90 deletions
diff --git a/src/common/db.h b/src/common/db.h
index 5a555b2fa..bf59e37d6 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -20,6 +20,7 @@
* - see what functions need or should be added to the database interface *
* *
* HISTORY: *
+ * 2013/08/25 - Added int64/uint64 support for keys *
* 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 *
@@ -38,12 +39,13 @@
* @encoding US-ASCII *
* @see common#db.c *
\*****************************************************************************/
-#ifndef _DB_H_
-#define _DB_H_
+#ifndef COMMON_DB_H
+#define COMMON_DB_H
-#include "../common/cbasetypes.h"
#include <stdarg.h>
+#include "../common/cbasetypes.h"
+
/*****************************************************************************\
* (1) Section with public typedefs, enums, unions, structures and defines. *
* DBRelease - Enumeration of release options. *
@@ -77,12 +79,14 @@ typedef enum DBRelease {
/**
* Supported types of database.
- * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
+ * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
* types of databases.
* @param DB_INT Uses int's for keys
* @param DB_UINT Uses unsigned int's for keys
* @param DB_STRING Uses strings for keys.
* @param DB_ISTRING Uses case insensitive strings for keys.
+ * @param DB_INT64 Uses int64's for keys
+ * @param DB_UINT64 Uses uint64's for keys
* @public
* @see #DBOptions
* @see #DBKey
@@ -96,21 +100,23 @@ typedef enum DBType {
DB_INT,
DB_UINT,
DB_STRING,
- DB_ISTRING
+ DB_ISTRING,
+ DB_INT64,
+ DB_UINT64,
} DBType;
/**
- * Bitfield of options that define the behaviour of the database.
- * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
+ * Bitfield of options that define the behavior of the database.
+ * See {@link #db_fix_options(DBType,DBOptions)} for restrictions of the
* types of databases.
* @param DB_OPT_BASE Base options: does not duplicate keys, releases nothing
* and does not allow NULL keys or NULL data.
- * @param DB_OPT_DUP_KEY Duplicates the keys internally. If DB_OPT_RELEASE_KEY
+ * @param DB_OPT_DUP_KEY Duplicates the keys internally. If DB_OPT_RELEASE_KEY
* is defined, the real key is freed as soon as the entry is added.
* @param DB_OPT_RELEASE_KEY Releases the key.
- * @param DB_OPT_RELEASE_DATA Releases the data whenever an entry is removed
+ * @param DB_OPT_RELEASE_DATA Releases the data whenever an entry is removed
* from the database.
- * WARNING: for funtions that return the data (like DBMap::remove),
+ * WARNING: for functions that return the data (like DBMap::remove),
* a dangling pointer will be returned.
* @param DB_OPT_RELEASE_BOTH Releases both key and data.
* @param DB_OPT_ALLOW_NULL_KEY Allow NULL keys in the database.
@@ -145,6 +151,8 @@ typedef union DBKey {
int i;
unsigned int ui;
const char *str;
+ int64 i64;
+ uint64 ui64;
} DBKey;
/**
@@ -158,7 +166,7 @@ typedef union DBKey {
typedef enum DBDataType {
DB_DATA_INT,
DB_DATA_UINT,
- DB_DATA_PTR
+ DB_DATA_PTR,
} DBDataType;
/**
@@ -180,7 +188,7 @@ typedef struct DBData {
} DBData;
/**
- * Format of functions that create the data for the key when the entry doesn't
+ * 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 function
@@ -192,9 +200,9 @@ typedef struct DBData {
typedef DBData (*DBCreateData)(DBKey key, va_list args);
/**
- * Format of functions to be applied 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
+ * 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
@@ -245,7 +253,7 @@ typedef int (*DBComparator)(DBKey key1, DBKey key2, unsigned short maxlen);
* @public
* @see #db_default_hash(DBType)
*/
-typedef unsigned int (*DBHasher)(DBKey key, unsigned short maxlen);
+typedef uint64 (*DBHasher)(DBKey key, unsigned short maxlen);
/**
* Format of the releaser used by the database system.
@@ -272,7 +280,7 @@ typedef struct DBMap DBMap;
* Database iterator.
* Supports forward iteration, backward iteration and removing entries from the database.
* The iterator is initially positioned before the first entry of the database.
- * While the iterator exists the database is locked internally, so invoke
+ * While the iterator exists the database is locked internally, so invoke
* {@link DBIterator#destroy} as soon as possible.
* @public
* @see #DBMap
@@ -326,7 +334,7 @@ struct DBIterator
/**
* Returns true if the fetched entry exists.
- * The databases entries might have NULL data, so use this to to test if
+ * The databases entries might have NULL data, so use this to to test if
* the iterator is done.
* @param self Iterator
* @return true is the entry exists
@@ -336,7 +344,7 @@ struct DBIterator
/**
* Removes the current entry from the database.
- * NOTE: {@link DBIterator#exists} will return false until another entry
+ * NOTE: {@link DBIterator#exists} will return false until another entry
* is fetched
* Puts data of the removed entry in out_data, if out_data is not NULL.
* @param self Iterator
@@ -357,7 +365,7 @@ struct DBIterator
};
/**
- * Public interface of a database. Only contains funtions.
+ * Public interface of a database. Only contains functions.
* All the functions take the interface as the first argument.
* @public
* @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short)
@@ -367,7 +375,7 @@ struct DBMap {
/**
* 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
+ * 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
@@ -399,7 +407,7 @@ struct DBMap {
* 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
+ * 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 Database
* @param buf Buffer to put the data of the matched entries
@@ -417,7 +425,7 @@ struct DBMap {
* 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
+ * 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 Database
* @param buf Buffer to put the data of the matched entries
@@ -433,7 +441,7 @@ struct DBMap {
/**
* 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
+ * If the entry does not exist, an entry is added with the data returned by
* <code>create</code>.
* @param self Database
* @param key Key that identifies the entry
@@ -447,7 +455,7 @@ struct DBMap {
/**
* Get the data of the entry identified by the key.
- * If the entry does not exist, an entry is added with the data returned by
+ * If the entry does not exist, an entry is added with the data returned by
* <code>create</code>.
* @param self Database
* @param key Key that identifies the entry
@@ -544,7 +552,7 @@ struct DBMap {
* 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
+ * 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 applied to every entry before deleting
@@ -559,7 +567,7 @@ struct DBMap {
* 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
+ * 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 applied to every entry before deleting
@@ -598,75 +606,96 @@ 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 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 i64db_exists(db,k) ( (db)->exists((db),DB->i642key(k)) )
+#define ui64db_exists(db,k) ( (db)->exists((db),DB->ui642key(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) ( 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 i64db_get(db,k) ( DB->data2ptr((db)->get((db),DB->i642key(k))) )
+#define ui64db_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui642key(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) ( 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 i64db_iget(db,k) ( DB->data2i((db)->get((db),DB->i642key(k))) )
+#define ui64db_iget(db,k) ( DB->data2i((db)->get((db),DB->ui642key(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) ( 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 i64db_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i642key(k))) )
+#define ui64db_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui642key(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),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 i64db_put(db,k,d) ( (db)->put((db),DB->i642key(k),DB->ptr2data(d),NULL) )
+#define ui64db_put(db,k,d) ( (db)->put((db),DB->ui642key(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),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),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 i64db_iput(db,k,d) ( (db)->put((db),DB->i642key(k),DB->i2data(d),NULL) )
+#define ui64db_iput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->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),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 i64db_uiput(db,k,d) ( (db)->put((db),DB->i642key(k),DB->ui2data(d),NULL) )
+#define ui64db_uiput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->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 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 i64db_remove(db,k) ( (db)->remove((db),DB->i642key(k),NULL) )
+#define ui64db_remove(db,k) ( (db)->remove((db),DB->ui642key(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) ( 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 i64db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i642key(k),(f))) )
+#define ui64db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui642key(k),(f))) )
// Database creation and destruction macros
#define idb_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_INT,(opt),sizeof(int))
#define uidb_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_UINT,(opt),sizeof(unsigned int))
#define strdb_alloc(opt,maxlen) DB->alloc(__FILE__,__func__,__LINE__,DB_STRING,(opt),(maxlen))
#define stridb_alloc(opt,maxlen) DB->alloc(__FILE__,__func__,__LINE__,DB_ISTRING,(opt),(maxlen))
+#define i64db_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_INT64,(opt),sizeof(int64))
+#define ui64db_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_UINT64,(opt),sizeof(uint64))
#define db_destroy(db) ( (db)->destroy((db),NULL) )
// Other macros
-#define db_clear(db) ( (db)->clear(db,NULL) )
+#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_remove(dbi) ( (dbi)->remove(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) )
@@ -682,6 +711,8 @@ 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_i642key - Manual cast from 'int64' to 'DBKey'. *
+ * db_ui642key - Manual cast from 'uint64' 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'. *
@@ -728,7 +759,7 @@ DBComparator (*default_cmp) (DBType type);
DBHasher (*default_hash) (DBType type);
/**
- * Returns the default releaser for the specified type of database with the
+ * Returns the default releaser for the specified type of database with the
* specified options.
* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
* before choosing the releaser
@@ -757,7 +788,7 @@ DBReleaser (*custom_release) (DBRelease which);
/**
* Allocate a new database of the specified type.
- * It uses the default comparator, hasher and releaser of the specified
+ * It uses the default comparator, hasher and releaser of the specified
* database type and fixed options.
* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)}
* before creating the database.
@@ -765,7 +796,7 @@ DBReleaser (*custom_release) (DBRelease which);
* @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
+ * @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
@@ -803,6 +834,22 @@ DBKey (*ui2key) (unsigned int key);
DBKey (*str2key) (const char *key);
/**
+ * Manual cast from 'int64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey (*i642key) (int64 key);
+
+/**
+ * Manual cast from 'uint64' to the union DBKey.
+ * @param key Key to be casted
+ * @return The key as a DBKey union
+ * @public
+ */
+DBKey (*ui642key) (uint64 key);
+
+/**
* Manual cast from 'int' to the struct DBData.
* @param data Data to be casted
* @return The data as a DBData struct
@@ -882,12 +929,13 @@ struct linkdb_node {
typedef void (*LinkDBFunc)(void* key, void* data, va_list args);
-void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // 重複を考慮しない
-void linkdb_replace( struct linkdb_node** head, void *key, void* data); // 重複を考慮する
-void* linkdb_search ( struct linkdb_node** head, void *key);
-void* linkdb_erase ( struct linkdb_node** head, void *key);
-void linkdb_final ( struct linkdb_node** head );
-void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
+void linkdb_insert (struct linkdb_node** head, void *key, void* data); // Doesn't take into account duplicate keys
+void linkdb_replace (struct linkdb_node** head, void *key, void* data); // Takes into account duplicate keys
+void* linkdb_search (struct linkdb_node** head, void *key);
+void* linkdb_erase (struct linkdb_node** head, void *key);
+void linkdb_final (struct linkdb_node** head);
+void linkdb_vforeach(struct linkdb_node** head, LinkDBFunc func, va_list ap);
+void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
@@ -1090,8 +1138,8 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
do{ \
if( (__n) > VECTOR_CAPACITY(__vec) ) \
{ /* increase size */ \
- if( VECTOR_CAPACITY(__vec) == 0 ) SET_POINTER(VECTOR_DATA(__vec), aMalloc((__n)*sizeof(VECTOR_FIRST(__vec)))); /* allocate new */ \
- else SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
+ if( VECTOR_CAPACITY(__vec) == 0 ) VECTOR_DATA(__vec) = aMalloc((__n)*sizeof(VECTOR_FIRST(__vec))); /* allocate new */ \
+ else VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \
memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \
VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
} \
@@ -1103,7 +1151,7 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
} \
else if( (__n) < VECTOR_CAPACITY(__vec) ) \
{ /* reduce size */ \
- SET_POINTER(VECTOR_DATA(__vec), aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec)))); /* reallocate */ \
+ VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \
VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \
if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \
} \
@@ -1120,8 +1168,10 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
#define VECTOR_ENSURE(__vec,__n,__step) \
do{ \
size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \
- while( (__n) > _empty_ ) _empty_ += (__step); \
- if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \
+ if( (__n) > _empty_ ) { \
+ while( (__n) > _empty_ ) _empty_ += (__step); \
+ VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \
+ } \
}while(0)
@@ -1392,7 +1442,8 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
/// @param __heap Binary heap
/// @param __val Value
/// @param __topcmp Comparator
-#define BHEAP_PUSH(__heap,__val,__topcmp) \
+/// @param __swp Swapper
+#define BHEAP_PUSH(__heap,__val,__topcmp,__swp) \
do{ \
size_t _i_ = VECTOR_LENGTH(__heap); \
VECTOR_PUSH(__heap,__val); /* insert at end */ \
@@ -1401,7 +1452,7 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
size_t _parent_ = (_i_-1)/2; \
if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
break; /* done */ \
- swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
+ __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
_i_ = _parent_; \
} \
}while(0)
@@ -1418,7 +1469,8 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
///
/// @param __heap Binary heap
/// @param __topcmp Comparator
-#define BHEAP_POP(__heap,__topcmp) BHEAP_POPINDEX(__heap,0,__topcmp)
+/// @param __swp Swapper
+#define BHEAP_POP(__heap,__topcmp,__swp) BHEAP_POPINDEX(__heap,0,__topcmp,__swp)
@@ -1433,16 +1485,19 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
/// @param __heap Binary heap
/// @param __idx Index
/// @param __topcmp Comparator
-#define BHEAP_POPINDEX(__heap,__idx,__topcmp) \
+/// @param __swp Swapper
+#define BHEAP_POPINDEX(__heap,__idx,__topcmp,__swp) \
do{ \
size_t _i_ = __idx; \
VECTOR_INDEX(__heap,__idx) = VECTOR_POP(__heap); /* put last at index */ \
+ if( _i_ >= VECTOR_LENGTH(__heap)) /* removed last, nothing to do */ \
+ break; \
while( _i_ ) \
{ /* restore heap property in parents */ \
size_t _parent_ = (_i_-1)/2; \
if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)) < 0 ) \
break; /* done */ \
- swap(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
+ __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i_)); \
_i_ = _parent_; \
} \
while( _i_ < VECTOR_LENGTH(__heap) ) \
@@ -1454,12 +1509,12 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
break; /* done */ \
else if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) <= 0 ) \
{ /* left child */ \
- swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
+ __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
_i_ = _lchild_; \
} \
else \
{ /* right child */ \
- swap(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
+ __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
_i_ = _rchild_; \
} \
} \
@@ -1494,4 +1549,4 @@ void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
-#endif /* _DB_H_ */
+#endif /* COMMON_DB_H */