summaryrefslogtreecommitdiff
path: root/src/common/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/db.c')
-rw-r--r--src/common/db.c914
1 files changed, 500 insertions, 414 deletions
diff --git a/src/common/db.c b/src/common/db.c
index a2dc695..7a4fa70 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -13,488 +13,574 @@
#define ROOT_SIZE 4096
#ifdef MALLOC_DBN
static struct dbn *dbn_root[512], *dbn_free;
-static int dbn_root_rest=0,dbn_root_num=0;
+static int dbn_root_rest = 0, dbn_root_num = 0;
-static void * malloc_dbn(void)
+static void *malloc_dbn (void)
{
- struct dbn* ret;
-
- if(dbn_free==NULL){
- if(dbn_root_rest<=0){
- CREATE(dbn_root[dbn_root_num], struct dbn, ROOT_SIZE);
-
- dbn_root_rest=ROOT_SIZE;
- dbn_root_num++;
- }
- return &(dbn_root[dbn_root_num-1][--dbn_root_rest]);
- }
- ret=dbn_free;
- dbn_free = dbn_free->parent;
- return ret;
+ struct dbn *ret;
+
+ if (dbn_free == NULL)
+ {
+ if (dbn_root_rest <= 0)
+ {
+ CREATE (dbn_root[dbn_root_num], struct dbn, ROOT_SIZE);
+
+ dbn_root_rest = ROOT_SIZE;
+ dbn_root_num++;
+ }
+ return &(dbn_root[dbn_root_num - 1][--dbn_root_rest]);
+ }
+ ret = dbn_free;
+ dbn_free = dbn_free->parent;
+ return ret;
}
-static void free_dbn(struct dbn* add_dbn)
+static void free_dbn (struct dbn *add_dbn)
{
- add_dbn->parent = dbn_free;
- dbn_free = add_dbn;
+ add_dbn->parent = dbn_free;
+ dbn_free = add_dbn;
}
#endif
-static int strdb_cmp(struct dbt* table,void* a,void* b)
+static int strdb_cmp (struct dbt *table, void *a, void *b)
{
- if(table->maxlen)
- return strncmp(a,b,table->maxlen);
- return strcmp(a,b);
+ if (table->maxlen)
+ return strncmp (a, b, table->maxlen);
+ return strcmp (a, b);
}
-static unsigned int strdb_hash(struct dbt* table,void* a)
+static unsigned int strdb_hash (struct dbt *table, void *a)
{
- int i;
- unsigned int h;
- unsigned char *p=a;
-
- i=table->maxlen;
- if(i==0) i=0x7fffffff;
- for(h=0;*p && --i>=0;){
- h=(h*33 + *p++) ^ (h>>24);
- }
- return h;
+ int i;
+ unsigned int h;
+ unsigned char *p = a;
+
+ i = table->maxlen;
+ if (i == 0)
+ i = 0x7fffffff;
+ for (h = 0; *p && --i >= 0;)
+ {
+ h = (h * 33 + *p++) ^ (h >> 24);
+ }
+ return h;
}
-struct dbt* strdb_init(int maxlen)
+struct dbt *strdb_init (int maxlen)
{
- int i;
- struct dbt* table;
+ int i;
+ struct dbt *table;
- CREATE(table, struct dbt, 1);
+ CREATE (table, struct dbt, 1);
- table->cmp=strdb_cmp;
- table->hash=strdb_hash;
- table->maxlen=maxlen;
- for(i=0;i<HASH_SIZE;i++)
- table->ht[i]=NULL;
- return table;
+ table->cmp = strdb_cmp;
+ table->hash = strdb_hash;
+ table->maxlen = maxlen;
+ for (i = 0; i < HASH_SIZE; i++)
+ table->ht[i] = NULL;
+ return table;
}
-static int numdb_cmp(struct dbt* table,void* a,void* b)
+static int numdb_cmp (struct dbt *table, void *a, void *b)
{
- int ia,ib;
+ int ia, ib;
- ia=(int)a;
- ib=(int)b;
+ ia = (int) a;
+ ib = (int) b;
- if((ia^ib) & 0x80000000)
- return ia<0 ? -1 : 1;
+ if ((ia ^ ib) & 0x80000000)
+ return ia < 0 ? -1 : 1;
- return ia-ib;
+ return ia - ib;
}
-static unsigned int numdb_hash(struct dbt* table,void* a)
+static unsigned int numdb_hash (struct dbt *table, void *a)
{
- return (unsigned int)a;
+ return (unsigned int) a;
}
-struct dbt* numdb_init(void)
+struct dbt *numdb_init (void)
{
- int i;
- struct dbt* table;
+ int i;
+ struct dbt *table;
- CREATE(table, struct dbt, 1);
+ CREATE (table, struct dbt, 1);
- table->cmp=numdb_cmp;
- table->hash=numdb_hash;
- table->maxlen=sizeof(int);
- for(i=0;i<HASH_SIZE;i++)
- table->ht[i]=NULL;
- return table;
+ table->cmp = numdb_cmp;
+ table->hash = numdb_hash;
+ table->maxlen = sizeof (int);
+ for (i = 0; i < HASH_SIZE; i++)
+ table->ht[i] = NULL;
+ return table;
}
-void* db_search(struct dbt *table,void* key)
+void *db_search (struct dbt *table, void *key)
{
- struct dbn *p;
-
- for(p=table->ht[table->hash(table,key) % HASH_SIZE];p;){
- int c=table->cmp(table,key,p->key);
- if(c==0)
- return p->data;
- if(c<0)
- p=p->left;
- else
- p=p->right;
- }
- return NULL;
+ struct dbn *p;
+
+ for (p = table->ht[table->hash (table, key) % HASH_SIZE]; p;)
+ {
+ int c = table->cmp (table, key, p->key);
+ if (c == 0)
+ return p->data;
+ if (c < 0)
+ p = p->left;
+ else
+ p = p->right;
+ }
+ return NULL;
}
-void * db_search2(struct dbt *table, const char *key)
+void *db_search2 (struct dbt *table, const char *key)
{
- int i,sp;
- struct dbn *p,*pn,*stack[64];
- int slen = strlen(key);
-
- for(i=0;i<HASH_SIZE;i++){
- if((p=table->ht[i])==NULL)
- continue;
- sp=0;
- while(1){
- if (strncasecmp(key, p->key, slen) == 0)
- return p->data;
- if((pn=p->left)!=NULL){
- if(p->right){
- stack[sp++]=p->right;
- }
- p=pn;
- } else {
- if(p->right){
- p=p->right;
- } else {
- if(sp==0)
- break;
- p=stack[--sp];
- }
- }
- }
- }
- return 0;
+ int i, sp;
+ struct dbn *p, *pn, *stack[64];
+ int slen = strlen (key);
+
+ for (i = 0; i < HASH_SIZE; i++)
+ {
+ if ((p = table->ht[i]) == NULL)
+ continue;
+ sp = 0;
+ while (1)
+ {
+ if (strncasecmp (key, p->key, slen) == 0)
+ return p->data;
+ if ((pn = p->left) != NULL)
+ {
+ if (p->right)
+ {
+ stack[sp++] = p->right;
+ }
+ p = pn;
+ }
+ else
+ {
+ if (p->right)
+ {
+ p = p->right;
+ }
+ else
+ {
+ if (sp == 0)
+ break;
+ p = stack[--sp];
+ }
+ }
+ }
+ }
+ return 0;
}
-static void db_rotate_left(struct dbn *p,struct dbn **root)
+static void db_rotate_left (struct dbn *p, struct dbn **root)
{
- struct dbn * y = p->right;
- p->right = y->left;
- if (y->left !=0)
- y->left->parent = p;
- y->parent = p->parent;
-
- if (p == *root)
- *root = y;
- else if (p == p->parent->left)
- p->parent->left = y;
- else
- p->parent->right = y;
- y->left = p;
- p->parent = y;
+ struct dbn *y = p->right;
+ p->right = y->left;
+ if (y->left != 0)
+ y->left->parent = p;
+ y->parent = p->parent;
+
+ if (p == *root)
+ *root = y;
+ else if (p == p->parent->left)
+ p->parent->left = y;
+ else
+ p->parent->right = y;
+ y->left = p;
+ p->parent = y;
}
-static void db_rotate_right(struct dbn *p,struct dbn **root)
+static void db_rotate_right (struct dbn *p, struct dbn **root)
{
- struct dbn * y = p->left;
- p->left = y->right;
- if (y->right != 0)
- y->right->parent = p;
- y->parent = p->parent;
-
- if (p == *root)
- *root = y;
- else if (p == p->parent->right)
- p->parent->right = y;
- else
- p->parent->left = y;
- y->right = p;
- p->parent = y;
+ struct dbn *y = p->left;
+ p->left = y->right;
+ if (y->right != 0)
+ y->right->parent = p;
+ y->parent = p->parent;
+
+ if (p == *root)
+ *root = y;
+ else if (p == p->parent->right)
+ p->parent->right = y;
+ else
+ p->parent->left = y;
+ y->right = p;
+ p->parent = y;
}
-static void db_rebalance(struct dbn *p,struct dbn **root)
+static void db_rebalance (struct dbn *p, struct dbn **root)
{
- p->color = RED;
- while(p!=*root && p->parent->color==RED){ // rootは必ず黒で親は赤いので親の親は必ず存在する
- if (p->parent == p->parent->parent->left) {
- struct dbn *y = p->parent->parent->right;
- if (y && y->color == RED) {
- p->parent->color = BLACK;
- y->color = BLACK;
- p->parent->parent->color = RED;
- p = p->parent->parent;
- } else {
- if (p == p->parent->right) {
- p = p->parent;
- db_rotate_left(p, root);
- }
- p->parent->color = BLACK;
- p->parent->parent->color = RED;
- db_rotate_right(p->parent->parent, root);
- }
- } else {
- struct dbn* y = p->parent->parent->left;
- if (y && y->color == RED) {
- p->parent->color = BLACK;
- y->color = BLACK;
- p->parent->parent->color = RED;
- p = p->parent->parent;
- } else {
- if (p == p->parent->left) {
- p = p->parent;
- db_rotate_right(p, root);
- }
- p->parent->color = BLACK;
- p->parent->parent->color = RED;
- db_rotate_left(p->parent->parent, root);
- }
- }
- }
- (*root)->color=BLACK;
+ p->color = RED;
+ while (p != *root && p->parent->color == RED)
+ { // rootは必ず黒で親は赤いので親の親は必ず存在する
+ if (p->parent == p->parent->parent->left)
+ {
+ struct dbn *y = p->parent->parent->right;
+ if (y && y->color == RED)
+ {
+ p->parent->color = BLACK;
+ y->color = BLACK;
+ p->parent->parent->color = RED;
+ p = p->parent->parent;
+ }
+ else
+ {
+ if (p == p->parent->right)
+ {
+ p = p->parent;
+ db_rotate_left (p, root);
+ }
+ p->parent->color = BLACK;
+ p->parent->parent->color = RED;
+ db_rotate_right (p->parent->parent, root);
+ }
+ }
+ else
+ {
+ struct dbn *y = p->parent->parent->left;
+ if (y && y->color == RED)
+ {
+ p->parent->color = BLACK;
+ y->color = BLACK;
+ p->parent->parent->color = RED;
+ p = p->parent->parent;
+ }
+ else
+ {
+ if (p == p->parent->left)
+ {
+ p = p->parent;
+ db_rotate_right (p, root);
+ }
+ p->parent->color = BLACK;
+ p->parent->parent->color = RED;
+ db_rotate_left (p->parent->parent, root);
+ }
+ }
+ }
+ (*root)->color = BLACK;
}
-static void db_rebalance_erase(struct dbn *z,struct dbn **root)
+static void db_rebalance_erase (struct dbn *z, struct dbn **root)
{
- struct dbn *y = z, *x = NULL, *x_parent = NULL;
-
- if (y->left == NULL)
- x = y->right;
- else if (y->right == NULL)
- x = y->left;
- else {
- y = y->right;
- while (y->left != NULL)
- y = y->left;
- x = y->right;
- }
- if (y != z) { // 左右が両方埋まっていた時 yをzの位置に持ってきてzを浮かせる
- z->left->parent = y;
- y->left = z->left;
- if (y != z->right) {
- x_parent = y->parent;
- if (x) x->parent = y->parent;
- y->parent->left = x;
- y->right = z->right;
- z->right->parent = y;
- } else
- x_parent = y;
- if (*root == z)
- *root = y;
- else if (z->parent->left == z)
- z->parent->left = y;
- else
- z->parent->right = y;
- y->parent = z->parent;
- { int tmp=y->color; y->color=z->color; z->color=tmp; }
- y = z;
- } else { // どちらか空いていた場合 xをzの位置に持ってきてzを浮かせる
- x_parent = y->parent;
- if (x) x->parent = y->parent;
- if (*root == z)
- *root = x;
- else if (z->parent->left == z)
- z->parent->left = x;
- else
- z->parent->right = x;
- }
- // ここまで色の移動の除いて通常の2分木と同じ
- if (y->color != RED) { // 赤が消える分には影響無し
- while (x != *root && (x == NULL || x->color == BLACK))
- if (x == x_parent->left) {
- struct dbn* w = x_parent->right;
- if (w->color == RED) {
- w->color = BLACK;
- x_parent->color = RED;
- db_rotate_left(x_parent, root);
- w = x_parent->right;
- }
- 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;
- } else {
- if (w->right == NULL ||
- w->right->color == BLACK) {
- if (w->left) w->left->color = BLACK;
- w->color = RED;
- db_rotate_right(w, root);
- w = x_parent->right;
- }
- w->color = x_parent->color;
- x_parent->color = BLACK;
- if (w->right) w->right->color = BLACK;
- db_rotate_left(x_parent, root);
- break;
- }
- } else { // same as above, with right <-> left.
- struct dbn* w = x_parent->left;
- if (w->color == RED) {
- w->color = BLACK;
- x_parent->color = RED;
- db_rotate_right(x_parent, root);
- w = x_parent->left;
- }
- 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;
- } else {
- if (w->left == NULL ||
- w->left->color == BLACK) {
- if (w->right) w->right->color = BLACK;
- w->color = RED;
- db_rotate_left(w, root);
- w = x_parent->left;
- }
- w->color = x_parent->color;
- x_parent->color = BLACK;
- if (w->left) w->left->color = BLACK;
- db_rotate_right(x_parent, root);
- break;
- }
- }
- if (x) x->color = BLACK;
- }
+ struct dbn *y = z, *x = NULL, *x_parent = NULL;
+
+ if (y->left == NULL)
+ x = y->right;
+ else if (y->right == NULL)
+ x = y->left;
+ else
+ {
+ y = y->right;
+ while (y->left != NULL)
+ y = y->left;
+ x = y->right;
+ }
+ if (y != z)
+ { // 左右が両方埋まっていた時 yをzの位置に持ってきてzを浮かせる
+ z->left->parent = y;
+ y->left = z->left;
+ if (y != z->right)
+ {
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ y->parent->left = x;
+ y->right = z->right;
+ z->right->parent = y;
+ }
+ else
+ x_parent = y;
+ if (*root == z)
+ *root = y;
+ else if (z->parent->left == z)
+ z->parent->left = y;
+ else
+ z->parent->right = y;
+ y->parent = z->parent;
+ {
+ int tmp = y->color;
+ y->color = z->color;
+ z->color = tmp;
+ }
+ y = z;
+ }
+ else
+ { // どちらか空いていた場合 xをzの位置に持ってきてzを浮かせる
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ if (*root == z)
+ *root = x;
+ else if (z->parent->left == z)
+ z->parent->left = x;
+ else
+ z->parent->right = x;
+ }
+ // ここまで色の移動の除いて通常の2分木と同じ
+ if (y->color != RED)
+ { // 赤が消える分には影響無し
+ while (x != *root && (x == NULL || x->color == BLACK))
+ if (x == x_parent->left)
+ {
+ struct dbn *w = x_parent->right;
+ if (w->color == RED)
+ {
+ w->color = BLACK;
+ x_parent->color = RED;
+ db_rotate_left (x_parent, root);
+ w = x_parent->right;
+ }
+ 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;
+ }
+ else
+ {
+ if (w->right == NULL || w->right->color == BLACK)
+ {
+ if (w->left)
+ w->left->color = BLACK;
+ w->color = RED;
+ db_rotate_right (w, root);
+ w = x_parent->right;
+ }
+ w->color = x_parent->color;
+ x_parent->color = BLACK;
+ if (w->right)
+ w->right->color = BLACK;
+ db_rotate_left (x_parent, root);
+ break;
+ }
+ }
+ else
+ { // same as above, with right <-> left.
+ struct dbn *w = x_parent->left;
+ if (w->color == RED)
+ {
+ w->color = BLACK;
+ x_parent->color = RED;
+ db_rotate_right (x_parent, root);
+ w = x_parent->left;
+ }
+ 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;
+ }
+ else
+ {
+ if (w->left == NULL || w->left->color == BLACK)
+ {
+ if (w->right)
+ w->right->color = BLACK;
+ w->color = RED;
+ db_rotate_left (w, root);
+ w = x_parent->left;
+ }
+ w->color = x_parent->color;
+ x_parent->color = BLACK;
+ if (w->left)
+ w->left->color = BLACK;
+ db_rotate_right (x_parent, root);
+ break;
+ }
+ }
+ if (x)
+ x->color = BLACK;
+ }
}
-struct dbn* db_insert(struct dbt *table,void* key,void* data)
+struct dbn *db_insert (struct dbt *table, void *key, void *data)
{
- struct dbn *p,*priv;
- int c,hash;
-
- hash = table->hash(table,key) % HASH_SIZE;
- for(c=0,priv=NULL ,p = table->ht[hash];p;){
- c=table->cmp(table,key,p->key);
- if(c==0){ // replace
- if (table->release)
- table->release(p, 3);
- p->data=data;
- p->key=key;
- return p;
- }
- priv=p;
- if(c<0){
- p=p->left;
- } else {
- p=p->right;
- }
- }
+ struct dbn *p, *priv;
+ int c, hash;
+
+ hash = table->hash (table, key) % HASH_SIZE;
+ for (c = 0, priv = NULL, p = table->ht[hash]; p;)
+ {
+ c = table->cmp (table, key, p->key);
+ if (c == 0)
+ { // replace
+ if (table->release)
+ table->release (p, 3);
+ p->data = data;
+ p->key = key;
+ return p;
+ }
+ priv = p;
+ if (c < 0)
+ {
+ p = p->left;
+ }
+ else
+ {
+ p = p->right;
+ }
+ }
#ifdef MALLOC_DBN
- p=malloc_dbn();
+ p = malloc_dbn ();
#else
- CREATE(p, struct dbn, 1);
+ CREATE (p, struct dbn, 1);
#endif
- if(p==NULL){
- printf("out of memory : db_insert\n");
- return NULL;
- }
- p->parent= NULL;
- p->left = NULL;
- p->right = NULL;
- p->key = key;
- p->data = data;
- p->color = RED;
- if(c==0){ // hash entry is empty
- table->ht[hash] = p;
- p->color = BLACK;
- } else {
- if(c<0){ // left node
- priv->left = p;
- p->parent=priv;
- } else { // right node
- priv->right = p;
- p->parent=priv;
- }
- if(priv->color==RED){ // must rebalance
- db_rebalance(p,&table->ht[hash]);
- }
- }
- return p;
+ if (p == NULL)
+ {
+ printf ("out of memory : db_insert\n");
+ return NULL;
+ }
+ p->parent = NULL;
+ p->left = NULL;
+ p->right = NULL;
+ p->key = key;
+ p->data = data;
+ p->color = RED;
+ if (c == 0)
+ { // hash entry is empty
+ table->ht[hash] = p;
+ p->color = BLACK;
+ }
+ else
+ {
+ if (c < 0)
+ { // left node
+ priv->left = p;
+ p->parent = priv;
+ }
+ else
+ { // right node
+ priv->right = p;
+ p->parent = priv;
+ }
+ if (priv->color == RED)
+ { // must rebalance
+ db_rebalance (p, &table->ht[hash]);
+ }
+ }
+ return p;
}
-void* db_erase(struct dbt *table,void* key)
+void *db_erase (struct dbt *table, void *key)
{
- void *data;
- struct dbn *p;
- int c,hash;
-
- hash = table->hash(table,key) % HASH_SIZE;
- for(c=0,p = table->ht[hash];p;){
- c=table->cmp(table,key,p->key);
- if(c==0)
- break;
- if(c<0)
- p=p->left;
- else
- p=p->right;
- }
- if(!p)
- return NULL;
- data=p->data;
- db_rebalance_erase(p,&table->ht[hash]);
+ void *data;
+ struct dbn *p;
+ int c, hash;
+
+ hash = table->hash (table, key) % HASH_SIZE;
+ for (c = 0, p = table->ht[hash]; p;)
+ {
+ c = table->cmp (table, key, p->key);
+ if (c == 0)
+ break;
+ if (c < 0)
+ p = p->left;
+ else
+ p = p->right;
+ }
+ if (!p)
+ return NULL;
+ data = p->data;
+ db_rebalance_erase (p, &table->ht[hash]);
#ifdef MALLOC_DBN
- free_dbn(p);
+ free_dbn (p);
#else
- free(p);
+ free (p);
#endif
- return data;
+ return data;
}
-void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
+void db_foreach (struct dbt *table, int (*func) (void *, void *, va_list),
+ ...)
{
- int i,sp;
- // red-black treeなので64個stackがあれば2^32個ノードまで大丈夫
- struct dbn *p,*pn,*stack[64];
- va_list ap;
-
- va_start(ap,func);
- for(i=0;i<HASH_SIZE;i++){
- if((p=table->ht[i])==NULL)
- continue;
- sp=0;
- while(1){
- func(p->key,p->data,ap);
- if((pn=p->left)!=NULL){
- if(p->right){
- stack[sp++]=p->right;
- }
- p=pn;
- } else {
- if(p->right){
- p=p->right;
- } else {
- if(sp==0)
- break;
- p=stack[--sp];
- }
- }
- }
- }
- va_end(ap);
+ int i, sp;
+ // red-black treeなので64個stackがあれば2^32個ノードまで大丈夫
+ struct dbn *p, *pn, *stack[64];
+ va_list ap;
+
+ va_start (ap, func);
+ for (i = 0; i < HASH_SIZE; i++)
+ {
+ if ((p = table->ht[i]) == NULL)
+ continue;
+ sp = 0;
+ while (1)
+ {
+ func (p->key, p->data, ap);
+ if ((pn = p->left) != NULL)
+ {
+ if (p->right)
+ {
+ stack[sp++] = p->right;
+ }
+ p = pn;
+ }
+ else
+ {
+ if (p->right)
+ {
+ p = p->right;
+ }
+ else
+ {
+ if (sp == 0)
+ break;
+ p = stack[--sp];
+ }
+ }
+ }
+ }
+ va_end (ap);
}
-void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
+void db_final (struct dbt *table, int (*func) (void *, void *, va_list), ...)
{
- int i,sp;
- struct dbn *p,*pn,*stack[64];
- va_list ap;
-
- va_start(ap,func);
- for(i=0;i<HASH_SIZE;i++){
- if((p=table->ht[i])==NULL)
- continue;
- sp=0;
- while(1){
- if(func)
- func(p->key,p->data,ap);
- if((pn=p->left)!=NULL){
- if(p->right){
- stack[sp++]=p->right;
- }
- } else {
- if(p->right){
- pn=p->right;
- } else {
- if(sp==0)
- break;
- pn=stack[--sp];
- }
- }
+ int i, sp;
+ struct dbn *p, *pn, *stack[64];
+ va_list ap;
+
+ va_start (ap, func);
+ for (i = 0; i < HASH_SIZE; i++)
+ {
+ if ((p = table->ht[i]) == NULL)
+ continue;
+ sp = 0;
+ while (1)
+ {
+ if (func)
+ func (p->key, p->data, ap);
+ if ((pn = p->left) != NULL)
+ {
+ if (p->right)
+ {
+ stack[sp++] = p->right;
+ }
+ }
+ else
+ {
+ if (p->right)
+ {
+ pn = p->right;
+ }
+ else
+ {
+ if (sp == 0)
+ break;
+ pn = stack[--sp];
+ }
+ }
#ifdef MALLOC_DBN
- free_dbn(p);
+ free_dbn (p);
#else
- free(p);
+ free (p);
#endif
- p=pn;
- }
- }
- free(table);
- va_end(ap);
+ p = pn;
+ }
+ }
+ free (table);
+ va_end (ap);
}