mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-08 23:49:56 +00:00
util/slicesx: add MapKeys and MapValues from golang.org/x/exp/maps
Importing the ~deprecated golang.org/x/exp/maps as "xmaps" to not shadow the std "maps" was getting ugly. And using slices.Collect on an iterator is verbose & allocates more. So copy (x)maps.Keys+Values into our slicesx package instead. Updates #cleanup Updates #12912 Updates #14514 (pulled out of that change) Change-Id: I5e68d12729934de93cf4a9cd87c367645f86123a Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
17b881538a
commit
1e2e319e7d
@@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
"tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
@@ -75,7 +75,7 @@ func TestStressEvictions(t *testing.T) {
|
||||
for len(vm) < numKeys {
|
||||
vm[rand.Uint64()] = true
|
||||
}
|
||||
vals := xmaps.Keys(vm)
|
||||
vals := slicesx.MapKeys(vm)
|
||||
|
||||
c := Cache[uint64, bool]{
|
||||
MaxEntries: cacheSize,
|
||||
@@ -106,7 +106,7 @@ func TestStressBatchedEvictions(t *testing.T) {
|
||||
for len(vm) < numKeys {
|
||||
vm[rand.Uint64()] = true
|
||||
}
|
||||
vals := xmaps.Keys(vm)
|
||||
vals := slicesx.MapKeys(vm)
|
||||
|
||||
c := Cache[uint64, bool]{}
|
||||
|
||||
|
@@ -148,3 +148,43 @@ func FirstEqual[T comparable](s []T, v T) bool {
|
||||
func LastEqual[T comparable](s []T, v T) bool {
|
||||
return len(s) > 0 && s[len(s)-1] == v
|
||||
}
|
||||
|
||||
// MapKeys returns the values of the map m.
|
||||
//
|
||||
// The keys will be in an indeterminate order.
|
||||
//
|
||||
// It's equivalent to golang.org/x/exp/maps.Keys, which
|
||||
// unfortunately has the package name "maps", shadowing
|
||||
// the std "maps" package. This version exists for clarity
|
||||
// when reading call sites.
|
||||
//
|
||||
// As opposed to slices.Collect(maps.Keys(m)), this allocates
|
||||
// the returned slice once to exactly the right size, rather than
|
||||
// appending larger backing arrays as it goes.
|
||||
func MapKeys[M ~map[K]V, K comparable, V any](m M) []K {
|
||||
r := make([]K, 0, len(m))
|
||||
for k := range m {
|
||||
r = append(r, k)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// MapValues returns the values of the map m.
|
||||
//
|
||||
// The values will be in an indeterminate order.
|
||||
//
|
||||
// It's equivalent to golang.org/x/exp/maps.Values, which
|
||||
// unfortunately has the package name "maps", shadowing
|
||||
// the std "maps" package. This version exists for clarity
|
||||
// when reading call sites.
|
||||
//
|
||||
// As opposed to slices.Collect(maps.Values(m)), this allocates
|
||||
// the returned slice once to exactly the right size, rather than
|
||||
// appending larger backing arrays as it goes.
|
||||
func MapValues[M ~map[K]V, K comparable, V any](m M) []V {
|
||||
r := make([]V, 0, len(m))
|
||||
for _, v := range m {
|
||||
r = append(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/set"
|
||||
"tailscale.com/util/slicesx"
|
||||
"tailscale.com/util/syspolicy/internal"
|
||||
"tailscale.com/util/syspolicy/setting"
|
||||
)
|
||||
@@ -418,7 +419,7 @@ func (s *TestStore) NotifyPolicyChanged() {
|
||||
s.mu.RUnlock()
|
||||
return
|
||||
}
|
||||
cbs := xmaps.Values(s.cbs)
|
||||
cbs := slicesx.MapValues(s.cbs)
|
||||
s.mu.RUnlock()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
Reference in New Issue
Block a user