struct SilcHashTableStruct {
SilcHashTableEntry *table;
uint32 table_size;
+ uint32 entry_count;
SilcHashFunction hash;
SilcHashCompare compare;
SilcHashDestructor destructor;
void silc_hash_table_free(SilcHashTable ht)
{
+ SilcHashTableEntry e, tmp;
int i;
- for (i = 0; i < primesize[ht->table_size]; i++)
- if (ht->table[i]) {
+ for (i = 0; i < primesize[ht->table_size]; i++) {
+ e = ht->table[i];
+ while (e) {
if (ht->destructor)
- ht->destructor(ht->table[i]->key, ht->table[i]->context);
- silc_free(ht->table[i]);
+ ht->destructor(e->key, e->context);
+ tmp = e;
+ e = e->next;
+ silc_free(tmp);
}
+ }
silc_free(ht->table);
silc_free(ht);
return primesize[ht->table_size];
}
+/* Returns the number of the entires in the hash table. If there is more
+ entries in the table thatn the size of the hash table calling the
+ silc_hash_table_rehash is recommended. */
+
+uint32 silc_hash_table_count(SilcHashTable ht)
+{
+ return ht->entry_count;
+}
+
/* Adds new entry to the hash table. The `key' is hashed using the
hash function and the both `key' and `context' will be saved to the
hash table. This function quarantees that the entry is always added
e->next = silc_calloc(1, sizeof(*e->next));
e->next->key = key;
e->next->context = context;
+ ht->entry_count++;
} else {
/* New key */
*entry = silc_calloc(1, sizeof(**entry));
(*entry)->key = key;
(*entry)->context = context;
+ ht->entry_count++;
}
}
} else {
/* New key */
*entry = silc_calloc(1, sizeof(**entry));
+ ht->entry_count++;
}
(*entry)->key = key;
ht->destructor(e->key, e->context);
silc_free(e);
+ ht->entry_count--;
+
return TRUE;
}
void silc_hash_table_rehash(SilcHashTable ht, uint32 new_size)
{
+ int i;
+ SilcHashTableEntry *table, e, tmp;
+ uint32 table_size, size_index;
+
+ /* Take old hash table */
+ table = ht->table;
+ table_size = ht->table_size;
+
+ /* Allocate new table */
+ ht->table = silc_calloc(new_size ? silc_hash_table_primesize(new_size,
+ &size_index) :
+ silc_hash_table_primesize(ht->entry_count,
+ &size_index),
+ sizeof(*ht->table));
+ ht->table_size = size_index;
+
+ /* Rehash */
+ for (i = 0; i < primesize[table_size]; i++) {
+ e = table[i];
+ while (e) {
+ silc_hash_table_add(ht, e->key, e->context);
+ tmp = e;
+ e = e->next;
+
+ /* Remove old entry */
+ silc_free(tmp);
+ }
+ }
+ /* Remove old table */
+ silc_free(table);
}