diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-02-22 03:36:37 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-02-22 03:36:37 -0800 |
commit | 26f0db2ae285c260b18adf469511baad1bfee37b (patch) | |
tree | 9c9b0d3265f94dac399d2757da5d26cf5e3d6a35 /hash.c | |
parent | 2868a7009f04a40d52c27503a0a4feb50da5c877 (diff) | |
download | txr-26f0db2ae285c260b18adf469511baad1bfee37b.tar.gz txr-26f0db2ae285c260b18adf469511baad1bfee37b.tar.bz2 txr-26f0db2ae285c260b18adf469511baad1bfee37b.zip |
* hash.c (remhash): Rewrote buggy function.
It was decrementing the hash count without checking that
something was deleted from the chain. The deletion was done
incorrectly, without regard for the kind of comparison fucntion
used by the hash table.
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -342,9 +342,15 @@ val remhash(val hash, val key) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); val *pchain = vecref_l(h->table, num(h->hash_fun(key) % h->modulus)); - *pchain = alist_remove1(*pchain, key); - h->count--; - bug_unless (h->count >= 0); + val existing = h->assoc_fun(key, *pchain); + + if (existing) { + val loc = memq(existing, *pchain); + *pchain = nappend2(ldiff(*pchain, loc), cdr(loc)); + h->count--; + bug_unless (h->count >= 0); + } + return nil; } |