diff options
-rw-r--r-- | src/hsearch.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/hsearch.c b/src/hsearch.c index 0cc4aca..d8d395a 100644 --- a/src/hsearch.c +++ b/src/hsearch.c @@ -107,14 +107,14 @@ static int resize(struct htab *htab, size_t nel) return 1; } -static struct elem *lookup(struct htab *htab, const char *key, size_t hash) +static struct elem *lookup(struct htab *htab, const char *key, size_t hash, size_t dead) { size_t i, j; struct elem *e; for (i=hash,j=1; ; i+=j++) { e = htab->elems + (i & htab->mask); - if (!e->item.key || + if ((!e->item.key && (!e->hash || e->hash == dead)) || (e->hash==hash && STRCMP(e->item.key, key)==0)) break; } @@ -138,36 +138,38 @@ void htab_destroy(struct htab *htab) free(htab); } -static htab_entry *htab_find_item(struct htab *htab, const char* key) +static struct elem *htab_find_elem(struct htab *htab, const char* key) { size_t hash = keyhash(key, htab->seed); - struct elem *e = lookup(htab, key, hash); + struct elem *e = lookup(htab, key, hash, 0); if (e->item.key) { - return &e->item; + return e; } return 0; } htab_value* htab_find(struct htab *htab, const char* key) { - htab_entry *i = htab_find_item(htab, key); - if(i) return &i->data; - return 0; + struct elem *e = htab_find_elem(htab, key); + if(!e) return 0; + return &e->item.data; } int htab_delete(struct htab *htab, const char* key) { - htab_entry *i = htab_find_item(htab, key); - if(!i) return 0; - i->key = 0; + struct elem *e = htab_find_elem(htab, key); + if(!e) return 0; + e->item.key = 0; + e->hash = 0xdeadc0de; + --htab->used; return 1; } int htab_insert(struct htab *htab, char* key, htab_value value) { size_t hash = keyhash(key, htab->seed); - struct elem *e = lookup(htab, key, hash); + struct elem *e = lookup(htab, key, hash, 0xdeadc0de); if(e->item.key) { /* it's not allowed to overwrite existing data */ return 0; |