]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
hash: refactor hash_table_insert_node() and its callers reference
authorBaofeng Wang <baofeng.wang@dovecot.fi>
Tue, 17 May 2016 08:45:50 +0000 (11:45 +0300)
committerGitLab <gitlab@git.dovecot.net>
Fri, 3 Jun 2016 13:08:38 +0000 (16:08 +0300)
Refactor *changes* the behavior of hash_table_insert().
* hash_table_insert() will assert when a key already exsists.
And hash_table_update() remains updating value when a key already exsists.

Refactor also changes the argument list referred by all its callers:
* hash_table_insert/update/resize().

src/lib/hash.c
src/lib/hash.h

index 7f6e87db3f824474a0a99517bc6cc5e77c22844a..c1f5917c598be4b6f634c3d9e452314ec9a4b9f0 100644 (file)
@@ -52,6 +52,12 @@ struct hash_iterate_context {
        unsigned int pos;
 };
 
+enum hash_table_operation{
+       HASH_TABLE_OP_INSERT,
+       HASH_TABLE_OP_UPDATE,
+       HASH_TABLE_OP_RESIZE
+};
+
 static bool hash_table_resize(struct hash_table *table, bool grow);
 
 void hash_table_create(struct hash_table **table_r, pool_t node_pool,
@@ -199,26 +205,30 @@ bool hash_table_lookup_full(const struct hash_table *table,
        return TRUE;
 }
 
-static struct hash_node * ATTR_NOWARN_UNUSED_RESULT
+static void
 hash_table_insert_node(struct hash_table *table, void *key, void *value,
-                      bool check_existing)
+                            enum hash_table_operation opcode)
 {
        struct hash_node *node, *prev;
        unsigned int hash;
+       bool check_existing = TRUE;
 
        i_assert(key != NULL);
 
+       if(opcode == HASH_TABLE_OP_RESIZE)
+               check_existing = FALSE;
        hash = table->hash_cb(key);
 
        if (check_existing && table->removed_count > 0) {
                /* there may be holes, have to check everything */
                node = hash_table_lookup_node(table, key, hash);
                if (node != NULL) {
+                       i_assert(opcode == HASH_TABLE_OP_UPDATE);
                        node->value = value;
-                       return node;
+                       return;
                }
 
-                check_existing = FALSE;
+               check_existing = FALSE;
        }
 
        /* a) primary node */
@@ -228,13 +238,13 @@ hash_table_insert_node(struct hash_table *table, void *key, void *value,
 
                node->key = key;
                node->value = value;
-               return node;
+               return;
        }
-
        if (check_existing) {
                if (table->key_compare_cb(node->key, key) == 0) {
+                       i_assert(opcode == HASH_TABLE_OP_UPDATE);
                        node->value = value;
-                       return node;
+                       return;
                }
        }
 
@@ -246,11 +256,11 @@ hash_table_insert_node(struct hash_table *table, void *key, void *value,
 
                if (check_existing) {
                        if (table->key_compare_cb(node->key, key) == 0) {
+                               i_assert(opcode == HASH_TABLE_OP_UPDATE);
                                node->value = value;
-                               return node;
+                               return;
                        }
                }
-
                prev = node;
                node = node->next;
        }
@@ -258,7 +268,8 @@ hash_table_insert_node(struct hash_table *table, void *key, void *value,
        if (node == NULL) {
                if (table->frozen == 0 && hash_table_resize(table, TRUE)) {
                        /* resized table, try again */
-                       return hash_table_insert_node(table, key, value, FALSE);
+                       hash_table_insert_node(table, key, value, HASH_TABLE_OP_RESIZE);
+                       return;
                }
 
                if (table->free_nodes == NULL)
@@ -275,20 +286,16 @@ hash_table_insert_node(struct hash_table *table, void *key, void *value,
        node->value = value;
 
        table->nodes_count++;
-       return node;
 }
 
 void hash_table_insert(struct hash_table *table, void *key, void *value)
 {
-       struct hash_node *node;
-
-       node = hash_table_insert_node(table, key, value, TRUE);
-       node->key = key;
+       hash_table_insert_node(table, key, value, HASH_TABLE_OP_INSERT);
 }
 
 void hash_table_update(struct hash_table *table, void *key, void *value)
 {
-       hash_table_insert_node(table, key, value, TRUE);
+       hash_table_insert_node(table, key, value, HASH_TABLE_OP_UPDATE);
 }
 
 static void
@@ -463,7 +470,7 @@ static bool hash_table_resize(struct hash_table *table, bool grow)
                node = &old_nodes[i];
                if (node->key != NULL) {
                        hash_table_insert_node(table, node->key,
-                                              node->value, FALSE);
+                                              node->value, HASH_TABLE_OP_RESIZE);
                }
 
                for (node = node->next; node != NULL; node = next) {
@@ -471,7 +478,7 @@ static bool hash_table_resize(struct hash_table *table, bool grow)
 
                        if (node->key != NULL) {
                                hash_table_insert_node(table, node->key,
-                                                      node->value, FALSE);
+                                                      node->value, HASH_TABLE_OP_RESIZE);
                        }
                        free_node(table, node);
                }
index d48eddad1e2c340e0fcf82f6e4038a780c458429..d51d5cd8a5fea2790b8ccbe4329865db9293e9fd 100644 (file)
@@ -100,9 +100,11 @@ bool hash_table_lookup_full(const struct hash_table *table,
        hash_table_lookup_full((table)._table, lookup_key, orig_key_r, value_r)
 #endif
 
-/* Insert/update node in hash table. The difference is that hash_table_insert()
-   replaces the key in table to given one, while hash_table_update() doesnt. */
+/* Suppose to insert a new key-value node to the hash table.
+   If the key already exists, assert-crash. */
 void hash_table_insert(struct hash_table *table, void *key, void *value);
+/* If the key doesn't exists, do the exact same as hash_table_insert()
+   If the key already exists, preserve the original key and update only the value.*/
 void hash_table_update(struct hash_table *table, void *key, void *value);
 #define hash_table_insert(table, key, value) \
        hash_table_insert((table)._table, \