Commit 3cc5a532 authored by Paul Eggert's avatar Paul Eggert

Improve hashing quality when configured --with-wide-int.

* fns.c (hash_string): New function, taken from sxhash_string.
Do not discard information about ASCII character case; this
discarding is no longer needed.
(sxhash-string): Use it.  Change sig to match it.  Caller changed.
* lisp.h: Declare it.
* lread.c (hash_string): Remove, since we now use fns.c's version.
The fns.c version returns a wider integer if --with-wide-int is
specified, so this should help the quality of the hashing a bit.
parent b312a492
2011-07-08 Paul Eggert <eggert@cs.ucla.edu>
Improve hashing quality when configured --with-wide-int.
* fns.c (hash_string): New function, taken from sxhash_string.
Do not discard information about ASCII character case; this
discarding is no longer needed.
(sxhash-string): Use it. Change sig to match it. Caller changed.
* lisp.h: Declare it.
* lread.c (hash_string): Remove, since we now use fns.c's version.
The fns.c version returns a wider integer if --with-wide-int is
specified, so this should help the quality of the hashing a bit.
2011-07-07 Paul Eggert <eggert@cs.ucla.edu>
* emacs.c: Integer overflow minor fix.
......
......@@ -4098,25 +4098,33 @@ sweep_weak_hash_tables (void)
#define SXHASH_REDUCE(X) \
((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
/* Return a hash for string PTR which has length LEN. The hash
code returned is guaranteed to fit in a Lisp integer. */
/* Return a hash for string PTR which has length LEN. The hash value
can be any EMACS_UINT value. */
static EMACS_UINT
sxhash_string (unsigned char *ptr, EMACS_INT len)
EMACS_UINT
hash_string (char const *ptr, ptrdiff_t len)
{
unsigned char *p = ptr;
unsigned char *end = p + len;
char const *p = ptr;
char const *end = p + len;
unsigned char c;
EMACS_UINT hash = 0;
while (p != end)
{
c = *p++;
if (c >= 0140)
c -= 40;
hash = SXHASH_COMBINE (hash, c);
}
return hash;
}
/* Return a hash for string PTR which has length LEN. The hash
code returned is guaranteed to fit in a Lisp integer. */
static EMACS_UINT
sxhash_string (char const *ptr, ptrdiff_t len)
{
EMACS_UINT hash = hash_string (ptr, len);
return SXHASH_REDUCE (hash);
}
......@@ -4231,7 +4239,7 @@ sxhash (Lisp_Object obj, int depth)
/* Fall through. */
case Lisp_String:
hash = sxhash_string (SDATA (obj), SCHARS (obj));
hash = sxhash_string (SSDATA (obj), SBYTES (obj));
break;
/* This can be everything from a vector to an overlay. */
......
......@@ -2557,6 +2557,7 @@ extern void sweep_weak_hash_tables (void);
extern Lisp_Object Qcursor_in_echo_area;
extern Lisp_Object Qstring_lessp;
extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql;
EMACS_UINT hash_string (char const *, ptrdiff_t);
EMACS_UINT sxhash (Lisp_Object, int);
Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
......
......@@ -3647,8 +3647,6 @@ static Lisp_Object initial_obarray;
static size_t oblookup_last_bucket_number;
static size_t hash_string (const char *ptr, size_t len);
/* Get an error if OBARRAY is not an obarray.
If it is one, return it. */
......@@ -3891,23 +3889,6 @@ oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_I
XSETINT (tem, hash);
return tem;
}
static size_t
hash_string (const char *ptr, size_t len)
{
register const char *p = ptr;
register const char *end = p + len;
register unsigned char c;
register size_t hash = 0;
while (p != end)
{
c = *p++;
if (c >= 0140) c -= 40;
hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c;
}
return hash;
}
void
map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment