From 4adc1c2174d8143153162364d33e6358628b86ce Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 26 Jul 2023 11:08:03 -0700 Subject: [PATCH] maps: remove Keys and Values Preserve the names in case we want them to return an iterator. Keep the efficient runtime implementations for now, as we will probably want them under some name, perhaps KeysSlice and ValuesSlice. Fixes #61538 Change-Id: I6b03010bf071fb4531cb2f967dad46425962fcb8 Reviewed-on: https://go-review.googlesource.com/c/go/+/513476 Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Russ Cox --- src/maps/maps.go | 28 ------------ src/maps/maps_test.go | 100 ------------------------------------------ 2 files changed, 128 deletions(-) diff --git a/src/maps/maps.go b/src/maps/maps.go index 4dabb7caa3317..befde18c9c973 100644 --- a/src/maps/maps.go +++ b/src/maps/maps.go @@ -5,34 +5,6 @@ // Package maps defines various functions useful with maps of any type. package maps -import "unsafe" - -// keys is implemented in the runtime package. -// -//go:noescape -func keys(m any, slice unsafe.Pointer) - -// Keys returns the keys of the map m. -// The keys will be in an indeterminate order. -func Keys[M ~map[K]V, K comparable, V any](m M) []K { - r := make([]K, 0, len(m)) - keys(m, unsafe.Pointer(&r)) - return r -} - -// values is implemented in the runtime package. -// -//go:noescape -func values(m any, slice unsafe.Pointer) - -// Values returns the values of the map m. -// The values will be in an indeterminate order. -func Values[M ~map[K]V, K comparable, V any](m M) []V { - r := make([]V, 0, len(m)) - values(m, unsafe.Pointer(&r)) - return r -} - // Equal reports whether two maps contain the same key/value pairs. // Values are compared using ==. func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool { diff --git a/src/maps/maps_test.go b/src/maps/maps_test.go index dc803e2dbc282..5e3f9ca03b1a0 100644 --- a/src/maps/maps_test.go +++ b/src/maps/maps_test.go @@ -6,87 +6,13 @@ package maps import ( "math" - "slices" - "sort" "strconv" "testing" - "unsafe" ) var m1 = map[int]int{1: 2, 2: 4, 4: 8, 8: 16} var m2 = map[int]string{1: "2", 2: "4", 4: "8", 8: "16"} -func keysForBenchmarking[M ~map[K]V, K comparable, V any](m M, s []K) { - keys(m, unsafe.Pointer(&s)) -} - -func TestKeys(t *testing.T) { - want := []int{1, 2, 4, 8} - - got1 := Keys(m1) - sort.Ints(got1) - if !slices.Equal(got1, want) { - t.Errorf("Keys(%v) = %v, want %v", m1, got1, want) - } - - got2 := Keys(m2) - sort.Ints(got2) - if !slices.Equal(got2, want) { - t.Errorf("Keys(%v) = %v, want %v", m2, got2, want) - } - - // test for oldbucket code path - // We grow from 128 to 256 buckets at size 832 (6.5 * 128). - // Then we have to evacuate 128 buckets, which means we'll be done evacuation at 832+128=960 elements inserted. - // so 840 is a good number to test for oldbucket code path. - var want3 []int - var m = make(map[int]int) - for i := 0; i < 840; i++ { - want3 = append(want3, i) - m[i] = i * i - } - - got3 := Keys(m) - sort.Ints(got3) - if !slices.Equal(got3, want3) { - t.Errorf("Keys(%v) = %v, want %v", m, got3, want3) - } -} - -func valuesForBenchmarking[M ~map[K]V, K comparable, V any](m M, s []V) { - values(m, unsafe.Pointer(&s)) -} - -func TestValues(t *testing.T) { - got1 := Values(m1) - want1 := []int{2, 4, 8, 16} - sort.Ints(got1) - if !slices.Equal(got1, want1) { - t.Errorf("Values(%v) = %v, want %v", m1, got1, want1) - } - - got2 := Values(m2) - want2 := []string{"16", "2", "4", "8"} - sort.Strings(got2) - if !slices.Equal(got2, want2) { - t.Errorf("Values(%v) = %v, want %v", m2, got2, want2) - } - - //test for oldbucket code path - var want3 []int - var m = make(map[int]int) - for i := 0; i < 840; i++ { - want3 = append(want3, i*i) - m[i] = i * i - } - - got3 := Values(m) - sort.Ints(got3) - if !slices.Equal(got3, want3) { - t.Errorf("Values(%v) = %v, want %v", m, got3, want3) - } -} - func TestEqual(t *testing.T) { if !Equal(m1, m1) { t.Errorf("Equal(%v, %v) = false, want true", m1, m1) @@ -256,29 +182,3 @@ func TestCloneWithMapAssign(t *testing.T) { } } } - -func BenchmarkKeys(b *testing.B) { - m := make(map[int]int, 1000000) - for i := 0; i < 1000000; i++ { - m[i] = i - } - b.ResetTimer() - - slice := make([]int, 0, len(m)) - for i := 0; i < b.N; i++ { - keysForBenchmarking(m, slice) - } -} - -func BenchmarkValues(b *testing.B) { - m := make(map[int]int, 1000000) - for i := 0; i < 1000000; i++ { - m[i] = i - } - b.ResetTimer() - - slice := make([]int, 0, len(m)) - for i := 0; i < b.N; i++ { - valuesForBenchmarking(m, slice) - } -}