mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 14:51:44 +00:00
chore: Add collection type - OrderedSet (#63469)
It is missing from the stdlib and the orderedmap library we're using.
This commit is contained in:
parent
ec90be4274
commit
e9108b33f7
@ -4,6 +4,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
go_library(
|
||||
name = "collections",
|
||||
srcs = [
|
||||
"ordered_set.go",
|
||||
"set.go",
|
||||
"slice_utils.go",
|
||||
],
|
||||
@ -11,6 +12,7 @@ go_library(
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//lib/errors",
|
||||
"@com_github_wk8_go_ordered_map_v2//:go-ordered-map",
|
||||
"@org_golang_x_exp//constraints",
|
||||
"@org_golang_x_exp//maps",
|
||||
],
|
||||
@ -20,6 +22,7 @@ go_test(
|
||||
name = "collections_test",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"ordered_set_test.go",
|
||||
"set_test.go",
|
||||
"slice_utils_test.go",
|
||||
],
|
||||
|
||||
45
internal/collections/ordered_set.go
Normal file
45
internal/collections/ordered_set.go
Normal file
@ -0,0 +1,45 @@
|
||||
package collections
|
||||
|
||||
import orderedmap "github.com/wk8/go-ordered-map/v2"
|
||||
|
||||
// OrderedSet keeps track of values in insertion order.
|
||||
type OrderedSet[T comparable] orderedmap.OrderedMap[T, struct{}]
|
||||
|
||||
// NewOrderedSet creates a OrderedSet[T] with the given values.
|
||||
// T must be a comparable type (implementing sort.Interface or == operator).
|
||||
func NewOrderedSet[T comparable](values ...T) *OrderedSet[T] {
|
||||
s := OrderedSet[T](*orderedmap.New[T, struct{}]())
|
||||
s.Add(values...)
|
||||
return &s
|
||||
}
|
||||
|
||||
func (s *OrderedSet[T]) impl() *orderedmap.OrderedMap[T, struct{}] {
|
||||
return (*orderedmap.OrderedMap[T, struct{}])(s)
|
||||
}
|
||||
|
||||
func (s *OrderedSet[T]) Add(values ...T) {
|
||||
for _, v := range values {
|
||||
s.impl().Set(v, struct{}{})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OrderedSet[T]) Remove(values ...T) {
|
||||
for _, v := range values {
|
||||
s.impl().Delete(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *OrderedSet[T]) Has(value T) bool {
|
||||
_, found := s.impl().Get(value)
|
||||
return found
|
||||
}
|
||||
|
||||
// Values returns a slice with all the values in the set.
|
||||
// The values are returned in insertion order.
|
||||
func (s *OrderedSet[T]) Values() []T {
|
||||
out := make([]T, 0, s.impl().Len())
|
||||
for x := s.impl().Oldest(); x != nil; x = x.Next() {
|
||||
out = append(out, x.Key)
|
||||
}
|
||||
return out
|
||||
}
|
||||
29
internal/collections/ordered_set_test.go
Normal file
29
internal/collections/ordered_set_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"pgregory.net/rapid"
|
||||
)
|
||||
|
||||
func TestOrderedSet(t *testing.T) {
|
||||
rapid.Check(t, func(t *rapid.T) {
|
||||
data := rapid.SliceOfN(rapid.IntRange(-3, 6), 0, 10).Draw(t, "data")
|
||||
set := NewSet(data...)
|
||||
uniquedData := set.Values()
|
||||
ordset := NewOrderedSet(uniquedData...)
|
||||
require.Equal(t, uniquedData, ordset.Values())
|
||||
|
||||
otherData := rapid.SliceOfN(rapid.IntRange(-5, 5), 10, 10).Draw(t, "data")
|
||||
for _, x := range otherData {
|
||||
require.Equal(t, set.Has(x), ordset.Has(x))
|
||||
}
|
||||
|
||||
for _, x := range uniquedData {
|
||||
require.True(t, ordset.Has(x))
|
||||
ordset.Remove(x)
|
||||
require.False(t, ordset.Has(x))
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user