summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}