[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