summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--ChangeLog8
-rw-r--r--hash.c12
2 files changed, 17 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ebd302d9..63434df7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2012-02-22 Kaz Kylheku <kaz@kylheku.com>
+ * 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.
+
+2012-02-22 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (eval_init): Intrinsic bindings for sub, ref, refset
and replace.
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;
}