* 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-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.
#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);
}
/* 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. */
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,
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. */
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;
-}
\f
void
map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg)