changeset 974:d9df59a406fb HEAD

Still more fixes
author Timo Sirainen <tss@iki.fi>
date Tue, 14 Jan 2003 14:09:33 +0200
parents d634f81c1217
children 7bd8508ed0fa
files src/lib/hash.c
diffstat 1 files changed, 21 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/hash.c	Tue Jan 14 13:43:01 2003 +0200
+++ b/src/lib/hash.c	Tue Jan 14 14:09:33 2003 +0200
@@ -51,7 +51,7 @@
 	hash_cmp_callback_t key_compare_cb;
 };
 
-static int hash_resize(struct hash_table *table);
+static int hash_resize(struct hash_table *table, int grow);
 
 static int foreach_stop;
 
@@ -72,18 +72,19 @@
 {
 	struct hash_table *table;
 
+	initial_size = 0;
+
 	table = p_new(table_pool, struct hash_table, 1);
         table->table_pool = table_pool;
 	table->node_pool = node_pool;
-	table->initial_size = initial_size;
+	table->initial_size =
+		I_MAX(primes_closest(initial_size), HASH_TABLE_MIN_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->size = table->initial_size;
 	table->nodes = p_new(table_pool, struct hash_node, table->size);
 	return table;
 }
@@ -247,7 +248,7 @@
 	}
 
 	if (node == NULL) {
-		if (table->frozen == 0 && hash_resize(table)) {
+		if (table->frozen == 0 && hash_resize(table, TRUE)) {
 			/* resized table, try again */
 			return hash_insert_node(table, key, value, FALSE);
 		}
@@ -332,7 +333,7 @@
 
 	if (table->frozen != 0)
 		table->removed_count++;
-	else if (!hash_resize(table))
+	else if (!hash_resize(table, FALSE))
 		hash_compress(table, &table->nodes[hash % table->size]);
 }
 
@@ -387,28 +388,34 @@
 		return;
 
 	if (table->removed_count > 0) {
-		if (!hash_resize(table))
+		if (!hash_resize(table, FALSE))
 			hash_compress_removed(table);
 	}
 }
 
-static int hash_resize(struct hash_table *table)
+static int hash_resize(struct hash_table *table, int grow)
 {
 	struct hash_node *old_nodes, *node, *next;
-	size_t old_size, i;
+	size_t next_size, old_size, i;
 	float nodes_per_list;
 
         nodes_per_list = (float) table->nodes_count / (float) table->size;
-        if ((nodes_per_list > 0.3 || table->size <= table->initial_size) &&
-            (nodes_per_list < 2.0))
+	if (nodes_per_list > 0.3 && nodes_per_list < 2.0)
+		return FALSE;
+
+	next_size = I_MAX(primes_closest(table->nodes_count+1),
+			  table->initial_size);
+	if (next_size == table->size)
+		return FALSE;
+
+	if (grow && table->size >= next_size)
 		return FALSE;
 
 	/* recreate primary table */
 	old_size = table->size;
 	old_nodes = table->nodes;
 
-	table->size = I_MAX(primes_closest(table->nodes_count+1),
-			    HASH_TABLE_MIN_SIZE);
+	table->size = I_MAX(next_size, HASH_TABLE_MIN_SIZE);
 	table->nodes = p_new(table->table_pool, struct hash_node, table->size);
 
 	table->nodes_count = 0;