diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-06-18 22:03:25 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-06-18 22:03:25 -0700 |
commit | 70890e6941a4bdbfd0067b60260b7307a874d38b (patch) | |
tree | 9e8d3c13599196754d6c8d8272942643b6ccae01 /hash.c | |
parent | ceea7281987c950e6bd5c72d7c93a5471a941e4e (diff) | |
download | txr-70890e6941a4bdbfd0067b60260b7307a874d38b.tar.gz txr-70890e6941a4bdbfd0067b60260b7307a874d38b.tar.bz2 txr-70890e6941a4bdbfd0067b60260b7307a874d38b.zip |
Improvements in equal hashing function.
* hash.c (equal_hash): For conses and vectors, ensure that
distinct permutations lead to different hash codes. This is done by
accumulating the partial hash with a multiplier, rather than just
adding subhashes.
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 13 |
1 files changed, 9 insertions, 4 deletions
@@ -126,7 +126,8 @@ static cnum equal_hash(val obj) case LIT: return hash_c_str(litptr(obj)) & NUM_MAX; case CONS: - return (equal_hash(obj->c.car) + equal_hash(obj->c.cdr)) & NUM_MAX; + return (equal_hash(obj->c.car) + + 32 * (equal_hash(obj->c.cdr) & (NUM_MAX / 16))) & NUM_MAX; case STR: return hash_c_str(obj->st.str) & NUM_MAX; case CHR: @@ -151,13 +152,17 @@ static cnum equal_hash(val obj) cnum i, h = equal_hash(obj->v.vec[vec_length]); cnum len = c_num(length); - for (i = 0; i < len; i++) - h = (h + equal_hash(obj->v.vec[i])) & NUM_MAX; + for (i = 0; i < len; i++) { + h = 32 * (h & (NUM_MAX / 16)); + h += equal_hash(obj->v.vec[i]); + h &= NUM_MAX; + } return h; } case LCONS: - return (equal_hash(car(obj)) + equal_hash(cdr(obj))) & NUM_MAX; + return (equal_hash(car(obj)) + + 32 * (equal_hash(cdr(obj)) & (NUM_MAX / 16))) & NUM_MAX; case LSTR: lazy_str_force(obj); return equal_hash(obj->ls.prefix); |