/* Jenkins's one_at_a_time hash; used to compute hash table index: */
-static inline int dict_hash(const char *key) {
+static inline uint32_t dict_hash(const char *key) {
size_t len = strlen(key);
uint32_t hash = 0;
dict_entry_t *e;
char *k;
void *v;
- unsigned h;
+ uint32_t h;
e = malloc(sizeof *e);
if (!e)
return d;
}
+/* Resize dictionary hash table: */
+int dict_resize(dict_t *d, size_t newsize) {
+ dict_entry_t **newht;
+
+ if (!d || !newsize) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (newsize == d->htsz)
+ return 0;
+ newht = malloc(newsize * sizeof *newht);
+ if (!newht)
+ return -1;
+ for (size_t i = 0; i < newsize; ++i )
+ newht[i] = NULL;
+ for (size_t i = 0; i < d->htsz; ++i ) {
+ uint32_t h;
+ dict_entry_t *next, *e;
+ for (e = d->ht[i]; e; e = next) {
+ h = dict_hash(e->key) % newsize;
+ next = e->next;
+ e->next = newht[h];
+ newht[h] = e;
+ }
+ }
+ free(d->ht);
+ d->ht = newht;
+ d->htsz = newsize;
+ return 0;
+}
+
/* Delete existing dictionary: */
int dict_delete(dict_t *d) {
if (!d)
*/
dict_t *dict_new(size_t ht_size);
+/*
+ * Resize dictionary hash table.
+ *
+ * Returns 0 on success, or -1 on error.
+ */
+int dict_resize(dict_t *d, size_t newsize);
+
/*
* Delete a dictionary previously created with dict_new() and release
* all resources associated with it.
assert( dict_remove(d, "foo") == 0 );
assert( dict_delete(d) == 0 );
- d = dict_new(2048);
+ d = dict_new(20480);
assert(d != NULL);
for (unsigned i = 0; i < 300000; ++i) {
char k[100], s[100];
cnt = 0;
assert( dict_foreach( d, dump_cb, &cnt) == 0);
dict_stat(d);
+
+ assert( dict_resize(d, 300000) == 0 );
+ dict_stat(d);
+
+ assert( dict_resize(d, 4096) == 0 );
+ dict_stat(d);
+
for (unsigned i = 0; i < 300000; ++i) {
char k[100];
sprintf(k, "%u %x", i, i);
- dict_remove(d, k);
+ assert( dict_remove(d, k) == 0 );
}
assert(dict_count(d) == 0);
- cnt = 0;
- assert( dict_foreach( d, dump_cb, &cnt) == 0);
dict_stat(d);
+
assert( dict_delete(d) == 0 );
return 0;