diff options
author | Keith Randall <khr@golang.org> | 2024-03-26 09:23:16 -0700 |
---|---|---|
committer | Keith Randall <khr@google.com> | 2024-03-26 21:33:31 +0000 |
commit | b47f2febea5c570fef4a5c27a46473f511fbdaa3 (patch) | |
tree | f0e3fac684f71bc62477fe5f05cf28b1435f3b93 /src/hash | |
parent | d3e5e9fdf64f7a4198a73244ab3900ca8ffbacbe (diff) | |
download | go-b47f2febea5c570fef4a5c27a46473f511fbdaa3.tar.gz go-b47f2febea5c570fef4a5c27a46473f511fbdaa3.zip |
runtime,hash/maphash: reuse hashSets to save memory pressure
Might help with OOMs on 32-bit platforms
Change-Id: Idd5129c61ecdfeedd5a9a18fce85dbba27cab946
Reviewed-on: https://go-review.googlesource.com/c/go/+/574475
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/hash')
-rw-r--r-- | src/hash/maphash/smhasher_test.go | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/src/hash/maphash/smhasher_test.go b/src/hash/maphash/smhasher_test.go index f34cea8e80..28cdae0444 100644 --- a/src/hash/maphash/smhasher_test.go +++ b/src/hash/maphash/smhasher_test.go @@ -112,6 +112,8 @@ func (s *hashSet) check(t *testing.T) { if float64(collisions) > expected+SLOP*(3*stddev+1) { t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f", collisions, expected, stddev) } + // Reset for reuse + s.list = s.list[:0] } // a string plus adding zeros must make distinct hashes @@ -212,8 +214,8 @@ func TestSmhasherCyclic(t *testing.T) { r := rand.New(rand.NewSource(1234)) const REPEAT = 8 const N = 1000000 + h := newHashSet() for n := 4; n <= 12; n++ { - h := newHashSet() b := make([]byte, REPEAT*n) for i := 0; i < N; i++ { b[0] = byte(i * 79 % 97) @@ -238,18 +240,18 @@ func TestSmhasherSparse(t *testing.T) { if testing.Short() { t.Skip("Skipping in short mode") } - sparse(t, 32, 6) - sparse(t, 40, 6) - sparse(t, 48, 5) - sparse(t, 56, 5) - sparse(t, 64, 5) - sparse(t, 96, 4) - sparse(t, 256, 3) - sparse(t, 2048, 2) -} -func sparse(t *testing.T, n int, k int) { - b := make([]byte, n/8) h := newHashSet() + sparse(t, h, 32, 6) + sparse(t, h, 40, 6) + sparse(t, h, 48, 5) + sparse(t, h, 56, 5) + sparse(t, h, 64, 5) + sparse(t, h, 96, 4) + sparse(t, h, 256, 3) + sparse(t, h, 2048, 2) +} +func sparse(t *testing.T, h *hashSet, n int, k int) { + b := make([]byte, n/8) setbits(h, b, 0, k) h.check(t) } @@ -276,15 +278,15 @@ func TestSmhasherPermutation(t *testing.T) { if testing.Short() { t.Skip("Skipping in short mode") } - permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8) - permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8) - permutation(t, []uint32{0, 1}, 20) - permutation(t, []uint32{0, 1 << 31}, 20) - permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 6) + h := newHashSet() + permutation(t, h, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8) + permutation(t, h, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8) + permutation(t, h, []uint32{0, 1}, 20) + permutation(t, h, []uint32{0, 1 << 31}, 20) + permutation(t, h, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 6) } -func permutation(t *testing.T, s []uint32, n int) { +func permutation(t *testing.T, h *hashSet, s []uint32, n int) { b := make([]byte, n*4) - h := newHashSet() genPerm(h, b, s, 0) h.check(t) } @@ -418,8 +420,8 @@ func windowed(t *testing.T, k key) { } const BITS = 16 + h := newHashSet() for r := 0; r < k.bits(); r++ { - h := newHashSet() for i := 0; i < 1<<BITS; i++ { k.clear() for j := 0; j < BITS; j++ { @@ -438,18 +440,18 @@ func TestSmhasherText(t *testing.T) { if testing.Short() { t.Skip("Skipping in short mode") } - text(t, "Foo", "Bar") - text(t, "FooBar", "") - text(t, "", "FooBar") + h := newHashSet() + text(t, h, "Foo", "Bar") + text(t, h, "FooBar", "") + text(t, h, "", "FooBar") } -func text(t *testing.T, prefix, suffix string) { +func text(t *testing.T, h *hashSet, prefix, suffix string) { const N = 4 const S = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789" const L = len(S) b := make([]byte, len(prefix)+N+len(suffix)) copy(b, prefix) copy(b[len(prefix)+N:], suffix) - h := newHashSet() c := b[len(prefix):] for i := 0; i < L; i++ { c[0] = S[i] |