[dovecot-cvs] dovecot/src/lib hash.c,1.13,1.14
cras at procontrol.fi
cras at procontrol.fi
Mon Jan 13 22:00:26 EET 2003
Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv24098
Modified Files:
hash.c
Log Message:
hash_resize() leaked memory, hash_insert/update didn't update value for
existing nodes.
Index: hash.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/hash.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- hash.c 11 Jan 2003 19:55:56 -0000 1.13
+++ hash.c 13 Jan 2003 20:00:23 -0000 1.14
@@ -50,10 +50,7 @@
pool_t table_pool, node_pool;
int frozen;
- size_t nodes_count, removed_count;
-#ifdef DEBUG
- size_t collisions_count;
-#endif
+ size_t initial_size, nodes_count, removed_count;
size_t size;
struct hash_node *nodes;
@@ -90,18 +87,20 @@
table = p_new(table_pool, struct hash_table, 1);
table->table_pool = table_pool;
- table->node_pool = node_pool;
- table->size = I_MAX(primes_closest(initial_size),
- HASH_TABLE_MIN_SIZE);
+ table->node_pool = node_pool;
+ table->initial_size = initial_size;
table->hash_cb = hash_cb != NULL ? hash_cb : direct_hash;
table->key_compare_cb = key_compare_cb == NULL ?
direct_cmp : key_compare_cb;
+
+ table->size = I_MAX(primes_closest(initial_size),
+ HASH_TABLE_MIN_SIZE);
+
table->nodes = p_new(table_pool, struct hash_node, table->size);
table->collisions_size = I_MAX(table->size / 10, COLLISIONS_MIN_SIZE);
table->collisions = p_new(table_pool, struct collision_node,
table->collisions_size);
-
return table;
}
@@ -166,9 +165,6 @@
table->nodes_count = 0;
table->removed_count = 0;
-#ifdef DEBUG
- table->collisions_count = 0;
-#endif
}
static struct hash_node *
@@ -247,8 +243,10 @@
if (check_existing && table->removed_count > 0) {
/* there may be holes, have to check everything */
node = hash_lookup_node(table, key, hash);
- if (node != NULL)
+ if (node != NULL) {
+ node->value = value;
return node;
+ }
check_existing = FALSE;
}
@@ -264,8 +262,10 @@
}
if (check_existing) {
- if (table->key_compare_cb(node->key, key) == 0)
+ if (table->key_compare_cb(node->key, key) == 0) {
+ node->value = value;
return node;
+ }
}
/* b) collisions list */
@@ -277,8 +277,10 @@
break;
if (check_existing) {
- if (table->key_compare_cb(cnode->node.key, key) == 0)
- return node;
+ if (table->key_compare_cb(cnode->node.key, key) == 0) {
+ cnode->node.value = value;
+ return &cnode->node;
+ }
}
prev = cnode;
@@ -305,9 +307,6 @@
cnode->node.key = key;
cnode->node.value = value;;
-#ifdef DEBUG
- table->collisions_count++;
-#endif
table->nodes_count++;
return &cnode->node;
}
@@ -340,9 +339,6 @@
if (next->node.key == NULL) {
cnode->next = next->next;
free_cnode(table, next);
-#ifdef DEBUG
- table->collisions_count--;
-#endif
}
}
@@ -359,9 +355,6 @@
memcpy(&croot->node, &next->node, sizeof(croot->node));
croot->next = next->next;
free_cnode(table, next);
-#ifdef DEBUG
- table->collisions_count--;
-#endif
}
/* see if node in primary table was deleted */
@@ -371,9 +364,6 @@
if (node->key == NULL) {
memcpy(node, &croot->node, sizeof(*node));
croot->node.key = NULL;
-#ifdef DEBUG
- table->collisions_count--;
-#endif
}
} while (croot->node.key == NULL);
}
@@ -484,14 +474,14 @@
static int hash_resize(struct hash_table *table)
{
struct hash_node *old_nodes;
- struct collision_node *old_cnodes, *cnode;
+ struct collision_node *old_cnodes, *cnode, *next;
size_t old_size, old_csize, i;
float nodes_per_list;
nodes_per_list = (float) table->nodes_count / (float) table->size;
- if ((nodes_per_list > 0.3 || table->size <= HASH_TABLE_MIN_SIZE) &&
+ if ((nodes_per_list > 0.3 || table->size <= table->initial_size) &&
(nodes_per_list < 2.0))
- return FALSE;
+ return FALSE;
/* recreate primary table */
old_size = table->size;
@@ -511,9 +501,6 @@
table->nodes_count = 0;
table->removed_count = 0;
-#ifdef DEBUG
- table->collisions_count = 0;
-#endif
table->frozen++;
@@ -528,13 +515,19 @@
for (i = 0; i < old_csize; i++) {
cnode = &old_cnodes[i];
- do {
+ if (cnode->node.key != NULL) {
+ hash_insert_node(table, cnode->node.key,
+ cnode->node.value, FALSE);
+ }
+
+ for (cnode = cnode->next; cnode != NULL; cnode = next) {
+ next = cnode->next;
if (cnode->node.key != NULL) {
hash_insert_node(table, cnode->node.key,
cnode->node.value, FALSE);
}
- cnode = cnode->next;
- } while (cnode != NULL);
+ free_cnode(table, cnode);
+ }
}
table->frozen--;
More information about the dovecot-cvs
mailing list