为了实现 x-lisp 中的 hash 和 set 两个数据类型, 需要能够计算每个数据的 hash code,作为 hash table 的 key。
polynomial rolling hash
| Bernstein (djb2) | h = h * 33 + c | | Java | h = h * 31 + c |
之所以用 31 是因为它是素数,并且是 2^5 - 1,因此乘法可以改为 shift。 Bernstein 选择 33 也是为此,虽然 33 不是素数。
h * 31 = h << 5 - h
h * 33 = h << 5 + h31 来自 "the c" book 的 144 页。
hash code of constants
java 中把 constant 的 hash code 取为了小素数:
true → 1231
false → 1237circular reference
java 的 Arrays.hashCode() 和 Objects.hashCode(), 不能处理理带有 circular reference 的数据。
最简单的处理 circular reference 的方案是 format 成 string, 然后用 string 的 hash code。
最简单的方式就是和 java 一样, hash code 不支持 circular reference。
因为 hash code 主要被用于 hash table 的 key, 而能够被作为 key 的 object,应该都是简单的数据, 不带有 circular reference。