int hash_table_remove(hash_table * hash_t, void *key, void **pdata) { hash_node **node, *dest; node = hash_table_lookup_node(hash_t, key); if (*node) { if (pdata != NULL) *pdata = (*node)->value; dest = *node; *node = dest->next; if (pdata == NULL) { if (hash_t->hash_free) hash_t->hash_free(dest->value); } diag_free(dest); hash_t->nnodes--; hash_table_resize(hash_t); return 1; } return 0; }
void *hash_table_lookup(const struct hash_table *table, const void *key) { struct hash_node *node; node = hash_table_lookup_node(table, key, table->hash_cb(key)); return node != NULL ? node->value : NULL; }
long hash_table_replace(hash_table * hash_t, void *key, void *value) { hash_node **node; hash_node *pnode; long hash_val; node = hash_table_lookup_node(hash_t, key); if (node) (*node)->value = value; else { *node = (hash_node *) diag_malloc(sizeof(hash_node)); if (*node == NULL) diag_fatal("Unable to allocate memory\n"); (*node)->key = key; (*node)->value = value; hash_val = (*hash_t->hash_func) ((*node)->key, hash_t->size); (*node)->next = hash_t->nodes[hash_val]; hash_t->nodes[hash_val] = (*node); hash_t->nnodes++; pnode = *node; hash_table_resize(hash_t); } return (long) pnode; }
long hash_table_get_id(hash_table * hash_t, void *key) { hash_node *node; node = *hash_table_lookup_node(hash_t, key); return (long)node; }
void * hash_table_lookup(hash_table * hash_t, void *key) { hash_node *node; node = *hash_table_lookup_node(hash_t, key); return node ? node->value : NULL; }
int hash_table_exists(hash_table * hash_t, void *key) { hash_node *node; node = *hash_table_lookup_node(hash_t, key); return node ? 1 : 0; }
bool hash_table_lookup_full(const struct hash_table *table, const void *lookup_key, void **orig_key, void **value) { struct hash_node *node; node = hash_table_lookup_node(table, lookup_key, table->hash_cb(lookup_key)); if (node == NULL) return FALSE; if (orig_key != NULL) *orig_key = node->key; if (value != NULL) *value = node->value; return TRUE; }
long hash_table_insert(hash_table * hash_t, void *key, void *value) { hash_node **node; hash_node *pnode; node = hash_table_lookup_node(hash_t, key); if (!*node) { *node = (hash_node *) diag_malloc(sizeof(hash_node)); if (*node == NULL) diag_fatal("Unable to allocate memory\n"); (*node)->key = key; (*node)->value = value; (*node)->next = NULL; hash_t->nnodes++; pnode = *node; hash_table_resize(hash_t); } return (long) pnode; }
static struct hash_node * hash_table_insert_node(struct hash_table *table, void *key, void *value, bool check_existing) { struct hash_node *node, *prev; unsigned int hash; i_assert(key != NULL); 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) { node->value = value; return node; } check_existing = FALSE; } /* a) primary node */ node = &table->nodes[hash % table->size]; if (node->key == NULL) { table->nodes_count++; node->key = key; node->value = value; return node; } if (check_existing) { if (table->key_compare_cb(node->key, key) == 0) { node->value = value; return node; } } /* b) collisions list */ prev = node; node = node->next; while (node != NULL) { if (node->key == NULL) break; if (check_existing) { if (table->key_compare_cb(node->key, key) == 0) { node->value = value; return node; } } prev = node; node = node->next; } 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); } if (table->free_nodes == NULL) node = p_new(table->node_pool, struct hash_node, 1); else { node = table->free_nodes; table->free_nodes = node->next; node->next = NULL; } prev->next = node; }