/** * Delete an entire hash table * * @param table The hash table to delete */ void hashtable_free(HASHTABLE *table) { int i; HASHENTRIES *entry, *ptr; if (table == NULL) { return; } hashtable_write_lock(table); for (i = 0; i < table->hashsize; i++) { entry = table->entries[i]; while (entry) { ptr = entry->next; table->kfreefn(entry->key); table->vfreefn(entry->value); free(entry); entry = ptr; } } free(table->entries); hashtable_write_unlock(table); if (!table->ht_isflat) { free(table); } }
/** * Delete an item from the hash table that has a given key * * @param table The hash table to delete from * @param key The key value of the item to remove * @return Return the number of items deleted */ int hashtable_delete(HASHTABLE *table, void *key) { int hashkey = table->hashfn(key) % table->hashsize; HASHENTRIES *entry, *ptr; hashtable_write_lock(table); entry = table->entries[hashkey % table->hashsize]; while (entry && entry->key && table->cmpfn(key, entry->key) != 0) { entry = entry->next; } if (entry == NULL) { /* Not found */ hashtable_write_unlock(table); return 0; } if (entry == table->entries[hashkey % table->hashsize]) { /* We are removing from the first entry */ table->entries[hashkey % table->hashsize] = entry->next; table->kfreefn(entry->key); table->vfreefn(entry->value); if (entry->next != NULL) { entry->key = entry->next->key; entry->value = entry->next->value; } else { entry->key = NULL; entry->value = NULL; } free(entry); } else { ptr = table->entries[hashkey % table->hashsize]; while (ptr && ptr->next != entry) ptr = ptr->next; if (ptr == NULL) { hashtable_write_unlock(table); return 0; /* This should never happen */ } ptr->next = entry->next; table->kfreefn(entry->key); table->vfreefn(entry->value); free(entry); } hashtable_write_unlock(table); return 1; }
/** * Add an item to the hash table. * * @param table The hash table to which to add the item * @param key The key of the item * @param value The value for the item * @return Return the number of items added */ int hashtable_add(HASHTABLE *table, void *key, void *value) { int hashkey; HASHENTRIES *entry; if (table->hashsize <= 0) { return 0; } else { hashkey = table->hashfn(key) % table->hashsize; } hashtable_write_lock(table); entry = table->entries[hashkey % table->hashsize]; while (entry && table->cmpfn(key, entry->key) != 0) { entry = entry->next; } if (entry && table->cmpfn(key, entry->key) == 0) { /* Duplicate key value */ hashtable_write_unlock(table); return 0; } else { HASHENTRIES *ptr = (HASHENTRIES *)malloc(sizeof(HASHENTRIES)); if (ptr == NULL) { hashtable_write_unlock(table); return 0; } ptr->key = table->kcopyfn(key); ptr->value = table->vcopyfn(value); ptr->next = table->entries[hashkey % table->hashsize]; table->entries[hashkey % table->hashsize] = ptr; } hashtable_write_unlock(table); return 1; }
/** * Delete an entire hash table * * @param table The hash table to delete */ void hashtable_free(HASHTABLE *table) { int i; HASHENTRIES *entry, *ptr; hashtable_write_lock(table); for (i = 0; i < table->hashsize; i++) { entry = table->entries[i]; while (entry) { ptr = entry->next; table->kfreefn(entry->key); table->vfreefn(entry->value); free(entry); entry = ptr; } } free(table->entries); free(table); }
/** * Add an item to the hash table. * * @param table The hash table to which to add the item * @param key The key of the item * @param value The value for the item * @return Return the number of items added */ int hashtable_add(HASHTABLE *table, void *key, void *value) { int hashkey; HASHENTRIES *entry; if (key == NULL || value == NULL) return 0; if (table->hashsize <= 0) { return 0; } else { hashkey = table->hashfn(key) % table->hashsize; } hashtable_write_lock(table); entry = table->entries[hashkey % table->hashsize]; while (entry && table->cmpfn(key, entry->key) != 0) { entry = entry->next; } if (entry && table->cmpfn(key, entry->key) == 0) { /* Duplicate key value */ hashtable_write_unlock(table); return 0; } else { HASHENTRIES *ptr = (HASHENTRIES *)malloc(sizeof(HASHENTRIES)); if (ptr == NULL) { hashtable_write_unlock(table); return 0; } /* copy the key */ ptr->key = table->kcopyfn(key); /* check succesfull key copy */ if ( ptr->key == NULL) { return 0; } /* copy the value */ ptr->value = table->vcopyfn(value); /* check succesfull value copy */ if ( ptr->value == NULL) { /* remove the key ! */ table->kfreefn(ptr->key); /* value not copied, return */ return 0; } ptr->next = table->entries[hashkey % table->hashsize]; table->entries[hashkey % table->hashsize] = ptr; } hashtable_write_unlock(table); return 1; }