internal/runtime/maps: proper capacity hint handling

When given a hint size, set the initial capacity large enough to avoid
requiring growth in the average case.

When not given a hint (or given 0), don't allocate anything at all.

For #54766.

Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest-swissmap
Change-Id: I8844fc652b8d2d4e5136cd56f7e78999a07fe381
Reviewed-on: https://go-review.googlesource.com/c/go/+/616457
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
This commit is contained in:
Michael Pratt 2024-09-12 10:44:38 -04:00 committed by Gopher Robot
parent 89d7f03172
commit 3b424cfa9d
12 changed files with 160 additions and 129 deletions

View file

@ -622,7 +622,10 @@ func TestConcurrentMapWrites(t *testing.T) {
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapWrites")
want := "fatal error: concurrent map writes\n"
if !strings.HasPrefix(output, want) {
// Concurrent writes can corrupt the map in a way that we
// detect with a separate throw.
want2 := "fatal error: small map with no empty slot (concurrent map writes?)\n"
if !strings.HasPrefix(output, want) && !strings.HasPrefix(output, want2) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}
@ -633,7 +636,10 @@ func TestConcurrentMapReadWrite(t *testing.T) {
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapReadWrite")
want := "fatal error: concurrent map read and map write\n"
if !strings.HasPrefix(output, want) {
// Concurrent writes can corrupt the map in a way that we
// detect with a separate throw.
want2 := "fatal error: small map with no empty slot (concurrent map writes?)\n"
if !strings.HasPrefix(output, want) && !strings.HasPrefix(output, want2) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}
@ -644,7 +650,10 @@ func TestConcurrentMapIterateWrite(t *testing.T) {
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapIterateWrite")
want := "fatal error: concurrent map iteration and map write\n"
if !strings.HasPrefix(output, want) {
// Concurrent writes can corrupt the map in a way that we
// detect with a separate throw.
want2 := "fatal error: small map with no empty slot (concurrent map writes?)\n"
if !strings.HasPrefix(output, want) && !strings.HasPrefix(output, want2) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}
@ -667,7 +676,10 @@ func TestConcurrentMapWritesIssue69447(t *testing.T) {
continue
}
want := "fatal error: concurrent map writes\n"
if !strings.HasPrefix(output, want) {
// Concurrent writes can corrupt the map in a way that we
// detect with a separate throw.
want2 := "fatal error: small map with no empty slot (concurrent map writes?)\n"
if !strings.HasPrefix(output, want) && !strings.HasPrefix(output, want2) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}