summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-02-22 03:36:37 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-02-22 03:36:37 -0800
commit26f0db2ae285c260b18adf469511baad1bfee37b (patch)
tree9c9b0d3265f94dac399d2757da5d26cf5e3d6a35 /hash.c
parent2868a7009f04a40d52c27503a0a4feb50da5c877 (diff)
downloadtxr-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.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/hash.c b/hash.c
index 32868569..d052c637 100644
--- a/hash.c
+++ b/hash.c
@@ -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;
}