diff options
| author | Paul Eggert | 2011-07-07 17:51:25 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-07 17:51:25 -0700 |
| commit | 3cc5a5328c43317b12a7163c4e1c0a56d85b93ce (patch) | |
| tree | 880e8f775ca3d34e357f1fda7ab2df57acd744aa /src | |
| parent | b312a4929d4ed7bc900a54f506905801f860ce7c (diff) | |
| download | emacs-3cc5a5328c43317b12a7163c4e1c0a56d85b93ce.tar.gz emacs-3cc5a5328c43317b12a7163c4e1c0a56d85b93ce.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/fns.c | 26 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/lread.c | 19 |
4 files changed, 30 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0265828c60e..aaf87deb9a5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2011-07-08 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Improve hashing quality when configured --with-wide-int. | ||
| 4 | * fns.c (hash_string): New function, taken from sxhash_string. | ||
| 5 | Do not discard information about ASCII character case; this | ||
| 6 | discarding is no longer needed. | ||
| 7 | (sxhash-string): Use it. Change sig to match it. Caller changed. | ||
| 8 | * lisp.h: Declare it. | ||
| 9 | * lread.c (hash_string): Remove, since we now use fns.c's version. | ||
| 10 | The fns.c version returns a wider integer if --with-wide-int is | ||
| 11 | specified, so this should help the quality of the hashing a bit. | ||
| 12 | |||
| 1 | 2011-07-07 Paul Eggert <eggert@cs.ucla.edu> | 13 | 2011-07-07 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 14 | ||
| 3 | * emacs.c: Integer overflow minor fix. | 15 | * emacs.c: Integer overflow minor fix. |
| @@ -4098,25 +4098,33 @@ sweep_weak_hash_tables (void) | |||
| 4098 | #define SXHASH_REDUCE(X) \ | 4098 | #define SXHASH_REDUCE(X) \ |
| 4099 | ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) | 4099 | ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) |
| 4100 | 4100 | ||
| 4101 | /* Return a hash for string PTR which has length LEN. The hash | 4101 | /* Return a hash for string PTR which has length LEN. The hash value |
| 4102 | code returned is guaranteed to fit in a Lisp integer. */ | 4102 | can be any EMACS_UINT value. */ |
| 4103 | 4103 | ||
| 4104 | static EMACS_UINT | 4104 | EMACS_UINT |
| 4105 | sxhash_string (unsigned char *ptr, EMACS_INT len) | 4105 | hash_string (char const *ptr, ptrdiff_t len) |
| 4106 | { | 4106 | { |
| 4107 | unsigned char *p = ptr; | 4107 | char const *p = ptr; |
| 4108 | unsigned char *end = p + len; | 4108 | char const *end = p + len; |
| 4109 | unsigned char c; | 4109 | unsigned char c; |
| 4110 | EMACS_UINT hash = 0; | 4110 | EMACS_UINT hash = 0; |
| 4111 | 4111 | ||
| 4112 | while (p != end) | 4112 | while (p != end) |
| 4113 | { | 4113 | { |
| 4114 | c = *p++; | 4114 | c = *p++; |
| 4115 | if (c >= 0140) | ||
| 4116 | c -= 40; | ||
| 4117 | hash = SXHASH_COMBINE (hash, c); | 4115 | hash = SXHASH_COMBINE (hash, c); |
| 4118 | } | 4116 | } |
| 4119 | 4117 | ||
| 4118 | return hash; | ||
| 4119 | } | ||
| 4120 | |||
| 4121 | /* Return a hash for string PTR which has length LEN. The hash | ||
| 4122 | code returned is guaranteed to fit in a Lisp integer. */ | ||
| 4123 | |||
| 4124 | static EMACS_UINT | ||
| 4125 | sxhash_string (char const *ptr, ptrdiff_t len) | ||
| 4126 | { | ||
| 4127 | EMACS_UINT hash = hash_string (ptr, len); | ||
| 4120 | return SXHASH_REDUCE (hash); | 4128 | return SXHASH_REDUCE (hash); |
| 4121 | } | 4129 | } |
| 4122 | 4130 | ||
| @@ -4231,7 +4239,7 @@ sxhash (Lisp_Object obj, int depth) | |||
| 4231 | /* Fall through. */ | 4239 | /* Fall through. */ |
| 4232 | 4240 | ||
| 4233 | case Lisp_String: | 4241 | case Lisp_String: |
| 4234 | hash = sxhash_string (SDATA (obj), SCHARS (obj)); | 4242 | hash = sxhash_string (SSDATA (obj), SBYTES (obj)); |
| 4235 | break; | 4243 | break; |
| 4236 | 4244 | ||
| 4237 | /* This can be everything from a vector to an overlay. */ | 4245 | /* This can be everything from a vector to an overlay. */ |
diff --git a/src/lisp.h b/src/lisp.h index 257c204e3b0..1e141dbb5d0 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2557,6 +2557,7 @@ extern void sweep_weak_hash_tables (void); | |||
| 2557 | extern Lisp_Object Qcursor_in_echo_area; | 2557 | extern Lisp_Object Qcursor_in_echo_area; |
| 2558 | extern Lisp_Object Qstring_lessp; | 2558 | extern Lisp_Object Qstring_lessp; |
| 2559 | extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; | 2559 | extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; |
| 2560 | EMACS_UINT hash_string (char const *, ptrdiff_t); | ||
| 2560 | EMACS_UINT sxhash (Lisp_Object, int); | 2561 | EMACS_UINT sxhash (Lisp_Object, int); |
| 2561 | Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, | 2562 | Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, |
| 2562 | Lisp_Object, Lisp_Object, Lisp_Object, | 2563 | Lisp_Object, Lisp_Object, Lisp_Object, |
diff --git a/src/lread.c b/src/lread.c index a9b69a1977b..6a97be2be42 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -3647,8 +3647,6 @@ static Lisp_Object initial_obarray; | |||
| 3647 | 3647 | ||
| 3648 | static size_t oblookup_last_bucket_number; | 3648 | static size_t oblookup_last_bucket_number; |
| 3649 | 3649 | ||
| 3650 | static size_t hash_string (const char *ptr, size_t len); | ||
| 3651 | |||
| 3652 | /* Get an error if OBARRAY is not an obarray. | 3650 | /* Get an error if OBARRAY is not an obarray. |
| 3653 | If it is one, return it. */ | 3651 | If it is one, return it. */ |
| 3654 | 3652 | ||
| @@ -3891,23 +3889,6 @@ oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_I | |||
| 3891 | XSETINT (tem, hash); | 3889 | XSETINT (tem, hash); |
| 3892 | return tem; | 3890 | return tem; |
| 3893 | } | 3891 | } |
| 3894 | |||
| 3895 | static size_t | ||
| 3896 | hash_string (const char *ptr, size_t len) | ||
| 3897 | { | ||
| 3898 | register const char *p = ptr; | ||
| 3899 | register const char *end = p + len; | ||
| 3900 | register unsigned char c; | ||
| 3901 | register size_t hash = 0; | ||
| 3902 | |||
| 3903 | while (p != end) | ||
| 3904 | { | ||
| 3905 | c = *p++; | ||
| 3906 | if (c >= 0140) c -= 40; | ||
| 3907 | hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c; | ||
| 3908 | } | ||
| 3909 | return hash; | ||
| 3910 | } | ||
| 3911 | 3892 | ||
| 3912 | void | 3893 | void |
| 3913 | map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg) | 3894 | map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg) |