From: Baofeng Wang Date: Tue, 17 May 2016 08:45:50 +0000 (+0300) Subject: hash: refactor hash_table_insert_node() and its callers reference X-Git-Tag: 2.3.0.rc1~3574 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b22ecd866f2503b48dc998323d183041d7a1f84;p=thirdparty%2Fdovecot%2Fcore.git hash: refactor hash_table_insert_node() and its callers reference 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(). --- diff --git a/src/lib/hash.c b/src/lib/hash.c index 7f6e87db3f..c1f5917c59 100644 --- a/src/lib/hash.c +++ b/src/lib/hash.c @@ -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); } diff --git a/src/lib/hash.h b/src/lib/hash.h index d48eddad1e..d51d5cd8a5 100644 --- a/src/lib/hash.h +++ b/src/lib/hash.h @@ -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, \