Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions locked.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ func (s *Locked[M]) Iterator(yield func(M) bool) {

// Clone returns a new set of the same underlying type.
func (s *Locked[M]) Clone() Set[M] {
s.RLock()
defer s.RUnlock()
return NewLockedFrom(s.Iterator)
}

Expand Down
2 changes: 0 additions & 2 deletions locked_ordered.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ func (s *LockedOrdered[M]) Iterator(yield func(M) bool) {

// Clone returns a new set of the same underlying type.
func (s *LockedOrdered[M]) Clone() Set[M] {
s.RLock()
defer s.RUnlock()
return NewLockedOrderedFrom(s.Iterator)
}

Expand Down
5 changes: 2 additions & 3 deletions ordered.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,8 @@ func (s *Ordered[M]) UnmarshalJSON(d []byte) error {
}

s.Clear()
s.values = t
for i, v := range s.values {
s.idx[v] = i
for _, v := range t {
s.Add(v)
}

return nil
Expand Down
6 changes: 5 additions & 1 deletion set.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ func Disjoint[K comparable](a, b Set[K]) bool {
// to the yield function. The index is not stable across iterations. The yield function is called for each element in the
// set. If the yield function returns false, the iteration is stopped.
func Iter2[K comparable](iter iter.Seq[K]) func(func(i int, k K) bool) {
var i int
return func(yield func(i int, k K) bool) {
var i int
for k := range iter {
if !yield(i, k) {
return
Expand Down Expand Up @@ -220,7 +220,11 @@ func Min[K cmp.Ordered](s Set[K]) K {
}

// Chunk the set into n sets of equal size. The last set will have fewer elements if the cardinality of the set is not a multiple of n.
// Panics if n <= 0.
func Chunk[K comparable](s Set[K], n int) iter.Seq[Set[K]] {
if n <= 0 {
panic("sets.Chunk: n must be > 0")
}
return func(yield func(Set[K]) bool) {
chunk := s.NewEmpty()
for i, v := range Iter2(s.Iterator) {
Expand Down
30 changes: 30 additions & 0 deletions set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1084,3 +1084,33 @@ func TestFirst_Last_LockedOrdered(t *testing.T) {
t.Fatalf("expected Last on empty set to return false")
}
}

func TestIter2ReusedIteratorResetsIndex(t *testing.T) {
t.Parallel()

s := New[int]()
s.Add(1)
s.Add(2)
s.Add(3)

iter2 := Iter2(s.Iterator)

// First iteration: collect all indices
var firstIndices []int
for i := range iter2 {
firstIndices = append(firstIndices, i)
}

// Second iteration: indices should start at 0 again
var secondIndices []int
for i := range iter2 {
secondIndices = append(secondIndices, i)
}

slices.Sort(firstIndices)
slices.Sort(secondIndices)

if diff := cmp.Diff(firstIndices, secondIndices); diff != "" {
t.Errorf("Iter2 indices differ on second invocation (-first +second):\n%s", diff)
}
}
10 changes: 6 additions & 4 deletions sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ type SyncMap[M comparable] struct {
m sync.Map
}

var _ Set[int] = new(SyncMap[int])
var _ driver.Valuer = new(SyncMap[int])
var (
_ Set[int] = new(SyncMap[int])
_ driver.Valuer = new(SyncMap[int])
)

// NewSyncMap returns an empty Set[M] that is backed by a sync.Map, making it safe for concurrent use.
// Please read the documentation for [sync.Map] to understand the behavior of modifying the map.
Expand Down Expand Up @@ -48,11 +50,11 @@ func (s *SyncMap[M]) Contains(m M) bool {

func (s *SyncMap[M]) Clear() int {
var n int
s.m.Range(func(_, _ interface{}) bool {
s.m.Range(func(k, _ any) bool {
s.m.Delete(k)
n++
return true
})
s.m.Clear()
return n
}

Expand Down
Loading