void hash_table_insert(struct hash_table* ht, hash_key_t k, hash_val_t v) { float load_factor = (float)ht->size / ht->capacity; if (load_factor >= HASH_TABLE_UPSIZE_LOAD_FACTOR) { size_t new_cap = ht->capacity * 2; hash_table_resize(ht, new_cap); } uint32_t hash = hash_key(ht, k); for (size_t i = 0; ; ++i) { size_t index = index_from_hash((hash + i), ht->capacity); uint32_t cur_hash = ht->hashes[index]; struct hash_entry* e = ht->table + index; /* Found empty or deleted slot, insert */ if (cur_hash == 0 || is_deleted(cur_hash)) { e->key = k; e->val = v; ht->hashes[index] = hash; ++ht->size; return; } /* Found occupied slot with same hash and key, replace value */ if (hash == cur_hash && ht->eql_fn(e->key, k)) { e->val = v; return; } } }
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; }
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; }
/** * Function to remove an hash table element (for a given key) from a given hash table * @param table hash table from which element has to be removed * @param key pointer to the key which has to be removed * @param key_len size of the key in bytes * @returns 0 on sucess * @returns -1 when key is not found */ int _cdecl hash_table_remove(hash_table_t * table, void * key, size_t key_len) { size_t hash; hash_table_element_t *temp, *prev; print_info("Deleting a key-value pair from the hash table\n"); if ((table->key_num/ table->key_count) >= table->key_ratio) { print_info("Ratio(%d) reached the set limit %d\nContracting hash_table\n", (table->key_num / table->key_count), table->key_ratio); hash_table_resize(table, table->key_num/2); //exit(0); } hash = HASH(key, key_len); if (!table->store_house[hash]) { print_info("Key Not Found -> No element at %d\n", (int)hash); return -1; // key not found } temp = table->store_house[hash]; prev = temp; while(temp) { while(temp && temp->key_len!=key_len) { prev = temp; temp = temp->next; } if(temp) { if (!memcmp(temp->key, key, key_len)) { if (prev == table->store_house[hash]) { table->store_house[hash] = temp->next; } else { prev->next = temp->next; } hash_table_element_delete(table, temp); print_info("Deleted a key-value pair from the hash table\n"); table->key_count--; return 0; } prev=temp; temp=temp->next; } } print_info("Key Not Found\n"); return -1; // key not found }
int hash_add_or_set(struct hash_table_t *ht, const char *key, unsigned int klen, void *val, unsigned int vlen, hash_ops op) { struct hash_bucket_t *p, **hlist_head; unsigned long h; unsigned int idx; h = ht->hash_func(key, klen); idx = h & ht->hash_mask; p = ht->buckets[idx]; for (; p; p = p->next) { if (p->hkey.klen == klen && !memcmp(p->hkey.key, key, klen)) {//Match if (op == HASH_ADD) { return 0; } UPDATE_VAL(ht, p, val, vlen); return 1; } } p = lkmalloc(sizeof(struct hash_bucket_t)); if (!p) return 0; hlist_head = &ht->buckets[idx]; INIT_KV(p, key, klen, val, vlen); INSERT_INTO_HLIST(p, hlist_head); INSERT_INTO_TLIST(p, ht); ht->elements_count++; if (ht->elements_count > ht->table_size) hash_table_resize(ht); return 1; }
void hash_table_insert(struct hash_table *hash, void *data, size_t size) { struct hash_element *element; element=(struct hash_element*)xmalloc(sizeof(*element)); element->data=data; element->hash=hash->hash_fun(data,size); set_hash_element(hash,element); hash->used++; if (hash->resize_load > 0.0 && hash_table_get_load(hash) >= hash->resize_load) hash_table_resize(hash,hash->resize_load); }
/* * Requires: * "key" is not already in "ht". * "value" is not NULL. * * Effects: * Creates an association or mapping from the string "key" to the pointer * "value" in the hash table "ht". Returns 0 if the mapping was successfully * created and -1 if it was not. */ int hash_table_insert(struct hash_table *ht, int key, void *value) { hash_table_mapping *elem; unsigned int index; assert(hash_table_lookup(ht, key) == NULL); assert(value != NULL); /* * Should the number of collision chains be increased? */ if (ht->occupancy >= ht->load_factor * ht->size) { /* * Try to double the number of collision chains. */ TracePrintf(1, "WARNING: hash table about to resize\n"); if (hash_table_resize(ht, ht->size * 2) == -1) return (-1); } /* * Allocate memory for a new mapping and initialize it. */ elem = malloc(sizeof (hash_table_mapping)); if (elem == NULL) return (-1); elem->key = key; elem->value = value; /* * Compute the array index of the collision chain in which the mapping * should be inserted. */ index = hash_value(key, ht) % ht->size; /* * Insert the new mapping into that collision chain. */ elem->next = ht->head[index]; ht->head[index] = elem; ht->occupancy++; return (0); }
void hash_table_set(hash_table * t, char * key, void * item){ int h = hash(t,key); element * e = (element *) malloc(sizeof(element)); e->key = malloc(strlen(key) + 1); e->item = item; strcpy(e->key,key); e->next = t->buckets[h]; t->buckets[h] = e; ++(t->count); //see how deep the chain goes int chain = 0; while(e != NULL){ e = e->next; chain++; } if(chain > MAX_CHAIN ){ hash_table_resize(t); } }
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; }
int hash_table_remove(HashTable *hash_table, HashTableKey key, bool resize) { HashTableEntry **rover; HashTableEntry *entry; unsigned long long int index; unsigned long long int result; /* If there are too few items in the table with respect to the table * size, the table is taking up too much space. * Shrink table to improve space efficiency. */ if (resize && (hash_table->entries * 8) / hash_table->table_size <= 0) { /* Table is less than 1/8 full */ if (!hash_table_resize(hash_table)) { /* Failed to enlarge the table */ return 0; } } /* Generate the hash of the key and hence the index into the table */ index = hash_table->hash_func(key) % hash_table->table_size; /* Rover points at the pointer which points at the current entry * in the chain being inspected. ie. the entry in the table, or * the "next" pointer of the previous entry in the chain. This * allows us to unlink the entry when we find it. */ result = 0; rover = &hash_table->table[index]; while (*rover != NULL) { if (hash_table->equal_func(key, (*rover)->key) != 0) { /* This is the entry to remove */ entry = *rover; /* Unlink from the list */ *rover = entry->next; /* Destroy the entry structure */ hash_table_free_entry(hash_table, entry); /* Track count of entries */ --hash_table->entries; result = 1; break; } /* Advance to the next entry */ rover = &((*rover)->next); } return result; }
int hash_table_insert(HashTable *hash_table, HashTableKey key, HashTableValue value) { HashTableEntry *rover; HashTableEntry *newentry; unsigned long long int index; /* If there are too many items in the table with respect to the table * size, the number of hash collisions increases and performance * decreases. Enlarge the table size to prevent this happening */ if ((hash_table->entries * 2) / hash_table->table_size > 0) { /* Table is more than 1/2 full */ if (!hash_table_resize(hash_table)) { /* Failed to enlarge the table */ return 0; } } /* Generate the hash of the key and hence the index into the table */ index = hash_table->hash_func(key) % hash_table->table_size; /* Traverse the chain at this location and look for an existing * entry with the same key */ rover = hash_table->table[index]; while (rover != NULL) { if (hash_table->equal_func(rover->key, key) != 0) { /* Same key: overwrite this entry with new data */ /* If there is a value free function, free the old data * before adding in the new data */ if (hash_table->value_free_func != NULL) { hash_table->value_free_func(rover->value); } /* Same with the key: use the new key value and free * the old one */ if (hash_table->key_free_func != NULL) { hash_table->key_free_func(rover->key); } rover->key = key; rover->value = value; /* Finished */ return 1; } rover = rover->next; } /* Not in the hash table yet. Create a new entry */ newentry = (HashTableEntry *) malloc(sizeof(HashTableEntry)); if (newentry == NULL) { return 0; } newentry->key = key; newentry->value = value; /* Link into the list */ newentry->next = hash_table->table[index]; hash_table->table[index] = newentry; /* Maintain the count of the number of entries */ ++hash_table->entries; /* Added successfully */ return 1; }
/** * Function to add a key - value pair to the hash table, use HT_ADD macro * @param table hash table to add element to * @param key pointer to the key for the hash table * @param key_len length of the key in bytes * @param value pointer to the value to be added against the key * @param value_len length of the value in bytes * @returns 0 on sucess * @returns -1 when no memory */ int _cdecl hash_table_add(hash_table_t * table, void * key, size_t key_len, void * value, size_t value_len) { size_t hash; hash_table_element_t * element; if ((table->key_count / table->key_num) >= table->key_ratio) { print_info("Ratio(%d) reached the set limit %d\nExpanding hash_table\n", (table->key_count / table->key_num), table->key_ratio); hash_table_resize(table, table->key_num*2); //exit(0); } hash = HASH(key, key_len); element = hash_table_element_new(); if (!element) { print_info("Cannot allocate memory for element\n"); return -1; // No Memory } if (table->mode == MODE_COPY) { print_info("Adding a key-value pair to the hash table with hash -> %d, in COPY MODE\n", (int)hash); element->key = malloc(key_len); element->value = malloc(value_len); if (element->key && element->value) { memcpy(element->key, key, key_len); memcpy(element->value, value, value_len); } else { if (element->key) { free(element->key); print_info("Cannot allocate memory for value\n"); } if (element->value) { free(element->value); print_info("Cannot allocate memory for key\n"); } free(element); return -1; //No Memory } } else if (table->mode == MODE_VALUEREF) { print_info("Adding a key-value pair to the hash table with hash -> %d, in VALUEREF MODE\n", (int)hash); element->key = malloc(key_len); if (element->key) { memcpy(element->key, key, key_len); } else { print_info("Cannot allocate memory for key\n"); free(element); return -1; //No Memory } element->value = value; } else if (table->mode == MODE_ALLREF) { print_info("Adding a key-value pair to the hash table with hash -> %d, in ALLREF MODE\n", (int)hash); element->key = key; element->value = value; } element->key_len = key_len; element->value_len = value_len; element->next = NULL; // find the key position for chaining if (!table->store_house[hash]) { print_info("No Conflicts adding the first element at %d\n", (int)hash); table->store_house[hash] = element; table->key_count++; } else { hash_table_element_t * temp = table->store_house[hash]; print_info("Conflicts adding element at %d\n", (int)hash); while(temp->next) { while(temp->next && temp->next->key_len!=key_len) { temp = temp->next; } if(temp->next) { if (!memcmp(temp->next->key, key, key_len)) { hash_table_element_t *to_delete = temp->next; print_info("Found Key at hash -> %d\n", (int)hash); temp->next = element; element->next = to_delete->next; hash_table_element_delete(table, to_delete); // since we are replacing values no need to change key_count return 0; } else { temp = temp->next; } } } temp->next = element; table->key_count++; } return 0; }