Skip to content

Commit

Permalink
maps: remove Keys and Values
Browse files Browse the repository at this point in the history
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 golang#61538

Change-Id: I6b03010bf071fb4531cb2f967dad46425962fcb8
Reviewed-on: https://go-review.googlesource.com/c/go/+/513476
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
  • Loading branch information
ianlancetaylor authored and eric committed Sep 7, 2023
1 parent 65b3ceb commit 4adc1c2
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 128 deletions.
28 changes: 0 additions & 28 deletions src/maps/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
100 changes: 0 additions & 100 deletions src/maps/maps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}

0 comments on commit 4adc1c2

Please sign in to comment.