From ffc02a9877e86d1a69638aa44ac9d10f37e20d62 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 7 Apr 2019 09:34:30 +0200 Subject: [PATCH] improve hash mixing original commit: d7469cedd67a950931a561ce14388fe7e628770d --- c/intern.c | 15 +++++++-------- s/newhash.ss | 3 ++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/c/intern.c b/c/intern.c index acfee35393..ddc478b7e4 100644 --- a/c/intern.c +++ b/c/intern.c @@ -188,19 +188,18 @@ void S_resize_oblist(void) { S_G.oblist = new_oblist; } -/* hash function: multiplier weights each character, h = n factors in the length */ -#define multiplier 3 +#define MIX_HASH(hc) (hc += (hc << 10), hc ^= (hc >> 6)) static iptr hash(const unsigned char *s, iptr n) { - iptr h = n + 401887359; - while (n--) h = h * multiplier + *s++; - return h & most_positive_fixnum; + uptr h = (uptr)n + 401887359; + while (n--) { h += *s++; MIX_HASH(h); } + return (iptr)h & most_positive_fixnum; } static iptr hash_sc(const string_char *s, iptr n) { - iptr h = n + 401887359; - while (n--) h = h * multiplier + Schar_value(*s++); - return h & most_positive_fixnum; + uptr h = (uptr)n + 401887359; + while (n--) { h += Schar_value(*s++); MIX_HASH(h); } + return (iptr)h & most_positive_fixnum; } static iptr hash_uname(const string_char *s, iptr n) { diff --git a/s/newhash.ss b/s/newhash.ss index 7af992bbf2..5afea1cfc4 100644 --- a/s/newhash.ss +++ b/s/newhash.ss @@ -920,7 +920,8 @@ Documentation notes: (define (hcabs hc) (if (fx< hc 0) (fxnot hc) hc)) (define (update hc k) - (fxlogxor (#3%fx+ (#3%fxsll hc 2) hc) k)) + (let ([hc2 (#3%fx+ hc (#3%fxsll (#3%fx+ hc k) 10))]) + (fxlogxor hc2 (fxsrl hc2 6)))) (define bytevector-hash (lambda (bv)