2025-10-15 10:12:44 +03:00

68 lines
1.4 KiB
Go

package collections
import "iter"
type SyncSet[T comparable] struct {
m SyncMap[T, struct{}]
}
func (s *SyncSet[T]) Has(key T) bool {
_, ok := s.m.Load(key)
return ok
}
func (s *SyncSet[T]) Add(key T) {
s.AddIfAbsent(key)
}
// AddIfAbsent adds the key to the set if it is not already present
// using LoadOrStore. It returns true if the key was not already present
// (opposite of the return value of LoadOrStore).
func (s *SyncSet[T]) AddIfAbsent(key T) bool {
_, loaded := s.m.LoadOrStore(key, struct{}{})
return !loaded
}
func (s *SyncSet[T]) Delete(key T) {
s.m.Delete(key)
}
func (s *SyncSet[T]) Range(fn func(key T) bool) {
s.m.Range(func(key T, value struct{}) bool {
return fn(key)
})
}
// Size returns the approximate number of items in the map.
// Note that this is not a precise count, as the map may be modified
// concurrently while this method is running.
func (s *SyncSet[T]) Size() int {
count := 0
s.m.Range(func(_ T, _ struct{}) bool {
count++
return true
})
return count
}
func (s *SyncSet[T]) ToSlice() []T {
var arr []T
arr = make([]T, 0, s.m.Size())
s.m.Range(func(key T, value struct{}) bool {
arr = append(arr, key)
return true
})
return arr
}
func (s *SyncSet[T]) Keys() iter.Seq[T] {
return func(yield func(T) bool) {
s.m.Range(func(key T, value struct{}) bool {
if !yield(key) {
return false
}
return true
})
}
}