Make better use of fixnum range in sxhash etc
Recent hash table changes reduced the range of sxhash, sxhash-eq etc to [0,2**32) on platforms with 62-bit fixnums. This change makes them use the full fixnum range again. Hash table hashing is unaffected. * src/fns.c (sxhash_eq, sxhash_eql): New. (hash_hash_to_fixnum): Replace with... (reduce_emacs_uint_to_fixnum): ...this. (hashfn_eq, hashfn_eql, Fsxhash_eq, Fsxhash_eql, Fsxhash_equal) (Fsxhash_equal_including_properties): Use the new functions.
This commit is contained in:
parent
7a87ca09a7
commit
50201e03b9
1 changed files with 25 additions and 20 deletions
45
src/fns.c
45
src/fns.c
|
@ -4462,14 +4462,26 @@ reduce_emacs_uint_to_hash_hash (EMACS_UINT x)
|
|||
: x ^ (x >> (8 * (sizeof x - sizeof (hash_hash_t)))));
|
||||
}
|
||||
|
||||
static EMACS_INT
|
||||
sxhash_eq (Lisp_Object key)
|
||||
{
|
||||
if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key))
|
||||
key = SYMBOL_WITH_POS_SYM (key);
|
||||
return XHASH (key) ^ XTYPE (key);
|
||||
}
|
||||
|
||||
static EMACS_INT
|
||||
sxhash_eql (Lisp_Object key)
|
||||
{
|
||||
return FLOATP (key) || BIGNUMP (key) ? sxhash (key) : sxhash_eq (key);
|
||||
}
|
||||
|
||||
/* Ignore H and return a hash code for KEY which uses 'eq' to compare keys. */
|
||||
|
||||
static hash_hash_t
|
||||
hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h)
|
||||
{
|
||||
if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key))
|
||||
key = SYMBOL_WITH_POS_SYM (key);
|
||||
return reduce_emacs_uint_to_hash_hash (XHASH (key) ^ XTYPE (key));
|
||||
return reduce_emacs_uint_to_hash_hash (sxhash_eq (key));
|
||||
}
|
||||
|
||||
/* Ignore H and return a hash code for KEY which uses 'equal' to
|
||||
|
@ -4484,8 +4496,7 @@ hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h)
|
|||
static hash_hash_t
|
||||
hashfn_eql (Lisp_Object key, struct Lisp_Hash_Table *h)
|
||||
{
|
||||
return (FLOATP (key) || BIGNUMP (key)
|
||||
? hashfn_equal (key, h) : hashfn_eq (key, h));
|
||||
return reduce_emacs_uint_to_hash_hash (sxhash_eql (key));
|
||||
}
|
||||
|
||||
/* Given H, return a hash code for KEY which uses a user-defined
|
||||
|
@ -5283,13 +5294,11 @@ collect_interval (INTERVAL interval, void *arg)
|
|||
Lisp Interface
|
||||
***********************************************************************/
|
||||
|
||||
/* Reduce X to a Lisp fixnum. */
|
||||
/* Reduce the hash value X to a Lisp fixnum. */
|
||||
static inline Lisp_Object
|
||||
hash_hash_to_fixnum (hash_hash_t x)
|
||||
reduce_emacs_uint_to_fixnum (EMACS_UINT x)
|
||||
{
|
||||
return make_ufixnum (FIXNUM_BITS < 8 * sizeof x
|
||||
? (x ^ x >> (8 * sizeof x - FIXNUM_BITS)) & INTMASK
|
||||
: x);
|
||||
return make_ufixnum (SXHASH_REDUCE (x));
|
||||
}
|
||||
|
||||
DEFUN ("sxhash-eq", Fsxhash_eq, Ssxhash_eq, 1, 1, 0,
|
||||
|
@ -5299,7 +5308,7 @@ If (eq A B), then (= (sxhash-eq A) (sxhash-eq B)).
|
|||
Hash codes are not guaranteed to be preserved across Emacs sessions. */)
|
||||
(Lisp_Object obj)
|
||||
{
|
||||
return hash_hash_to_fixnum (hashfn_eq (obj, NULL));
|
||||
return reduce_emacs_uint_to_fixnum (sxhash_eq (obj));
|
||||
}
|
||||
|
||||
DEFUN ("sxhash-eql", Fsxhash_eql, Ssxhash_eql, 1, 1, 0,
|
||||
|
@ -5310,7 +5319,7 @@ isn't necessarily true.
|
|||
Hash codes are not guaranteed to be preserved across Emacs sessions. */)
|
||||
(Lisp_Object obj)
|
||||
{
|
||||
return hash_hash_to_fixnum (hashfn_eql (obj, NULL));
|
||||
return reduce_emacs_uint_to_fixnum (sxhash_eql (obj));
|
||||
}
|
||||
|
||||
DEFUN ("sxhash-equal", Fsxhash_equal, Ssxhash_equal, 1, 1, 0,
|
||||
|
@ -5321,7 +5330,7 @@ opposite isn't necessarily true.
|
|||
Hash codes are not guaranteed to be preserved across Emacs sessions. */)
|
||||
(Lisp_Object obj)
|
||||
{
|
||||
return hash_hash_to_fixnum (hashfn_equal (obj, NULL));
|
||||
return reduce_emacs_uint_to_fixnum (sxhash (obj));
|
||||
}
|
||||
|
||||
DEFUN ("sxhash-equal-including-properties", Fsxhash_equal_including_properties,
|
||||
|
@ -5334,14 +5343,10 @@ If (sxhash-equal-including-properties A B), then
|
|||
Hash codes are not guaranteed to be preserved across Emacs sessions. */)
|
||||
(Lisp_Object obj)
|
||||
{
|
||||
EMACS_UINT hash = sxhash (obj);
|
||||
if (STRINGP (obj))
|
||||
{
|
||||
EMACS_UINT hash = 0;
|
||||
traverse_intervals (string_intervals (obj), 0, hash_interval, &hash);
|
||||
return make_ufixnum (SXHASH_REDUCE (sxhash_combine (sxhash (obj), hash)));
|
||||
}
|
||||
|
||||
return hash_hash_to_fixnum (hashfn_equal (obj, NULL));
|
||||
traverse_intervals (string_intervals (obj), 0, hash_interval, &hash);
|
||||
return reduce_emacs_uint_to_fixnum (hash);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue