diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-02-14 15:53:06 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-02-14 15:53:06 -0800 |
commit | ed290d6d0df5f4c694459f853983ab79929ea786 (patch) | |
tree | 0c410e2c702bd6d390a74a52813f552b6f0ad495 /hash.c | |
parent | 773063af1cf3bb5da145335f7d73a56e084a9c3e (diff) | |
download | txr-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.c | 22 |
1 files changed, 22 insertions, 0 deletions
@@ -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); |