Mercurial > hg > xemacs-beta
diff src/elhash.c @ 4398:479443c0f95a
Have list hashes depend on the order of the contents, as is the case for vectors.
src/ChangeLog addition:
2008-01-16 Aidan Kehoe <kehoea@parhasard.net>
* elhash.c (internal_hash):
Make short lists with the same contents in a different order hash
distinctly. Gives better performance for things like three-element
lists describing colours. Thank you Sebastian Freundt!
tests/ChangeLog addition:
2008-01-16 Aidan Kehoe <kehoea@parhasard.net>
* automated/hash-table-tests.el:
Assert that two short lists with the same contents in distinct
orders hash differently.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Wed, 16 Jan 2008 15:20:51 +0100 |
parents | 229bd619740a |
children | aae1994dfeec |
line wrap: on
line diff
--- a/src/elhash.c Wed Jan 16 00:19:59 2008 +0100 +++ b/src/elhash.c Wed Jan 16 15:20:51 2008 +0100 @@ -1719,12 +1719,33 @@ { if (depth > 5) return 0; - if (CONSP (obj)) + + if (CONSP(obj)) { - /* no point in worrying about tail recursion, since we're not - going very deep */ - return HASH2 (internal_hash (XCAR (obj), depth + 1), - internal_hash (XCDR (obj), depth + 1)); + Hashcode hash, h; + int s; + + depth += 1; + + if (!CONSP(XCDR(obj))) + { + /* special case for '(a . b) conses */ + return HASH2(internal_hash(XCAR(obj), depth), + internal_hash(XCDR(obj), depth)); + } + + /* Don't simply tail recurse; we want to hash lists with the + same contents in distinct orders differently. */ + hash = internal_hash(XCAR(obj), depth); + + obj = XCDR(obj); + for (s = 1; s < 6 && CONSP(obj); obj = XCDR(obj), s++) + { + h = internal_hash(XCAR(obj), depth); + hash = HASH3(hash, h, s); + } + + return hash; } if (STRINGP (obj)) {