summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-14 15:53:06 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-14 15:53:06 -0800
commited290d6d0df5f4c694459f853983ab79929ea786 (patch)
tree0c410e2c702bd6d390a74a52813f552b6f0ad495 /hash.c
parent773063af1cf3bb5da145335f7d73a56e084a9c3e (diff)
downloadtxr-ed290d6d0df5f4c694459f853983ab79929ea786.tar.gz
txr-ed290d6d0df5f4c694459f853983ab79929ea786.tar.bz2
txr-ed290d6d0df5f4c694459f853983ab79929ea786.zip
* eval.c (eval_init): Register inhash as intrinsic.
* hash.c (inhash): New function. * hash.h (inhash): Declared. * txr.1: Documented inhash. Also, added surprisingly missing documentation for gethash!
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/hash.c b/hash.c
index c74a6294..f9548c3c 100644
--- a/hash.c
+++ b/hash.c
@@ -542,6 +542,28 @@ val gethash(val hash, val key)
return cdr(found);
}
+val inhash(val hash, val key, val init)
+{
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
+ val found;
+
+ if (missingp(init)) {
+ val chain = vecref(h->table, num_fast(h->hash_fun(key) % h->modulus));
+ found = h->assoc_fun(key, chain);
+ } else {
+ val *pchain = vecref_l(h->table, num_fast(h->hash_fun(key) % h->modulus));
+ val old = *pchain, new;
+ val *place = h->acons_new_l_fun(key, &new, pchain);
+ if (old != *pchain && ++h->count > 2 * h->modulus)
+ hash_grow(h);
+ if (new)
+ *place = init;
+ found = h->assoc_fun(key, *pchain);
+ }
+
+ return found;
+}
+
val gethash_f(val hash, val key, val *found)
{
struct hash *h = (struct hash *) cobj_handle(hash, hash_s);