mattermost-community-enterp.../vendor/github.com/fatih/set/set_ts.go
Claude ec1f89217a Merge: Complete Mattermost Server with Community Enterprise
Full Mattermost server source with integrated Community Enterprise features.
Includes vendor directory for offline/air-gapped builds.

Structure:
- enterprise-impl/: Enterprise feature implementations
- enterprise-community/: Init files that register implementations
- enterprise/: Bridge imports (community_imports.go)
- vendor/: All dependencies for offline builds

Build (online):
  go build ./cmd/mattermost

Build (offline/air-gapped):
  go build -mod=vendor ./cmd/mattermost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 23:59:07 +09:00

195 lines
3.9 KiB
Go

package set
import "sync"
// Set defines a thread safe set data structure.
type Set struct {
set
l sync.RWMutex // we name it because we don't want to expose it
}
// New creates and initialize a new Set. It's accept a variable number of
// arguments to populate the initial set. If nothing passed a Set with zero
// size is created.
func newTS() *Set {
s := &Set{}
s.m = make(map[interface{}]struct{})
// Ensure interface compliance
var _ Interface = s
return s
}
// Add includes the specified items (one or more) to the set. The underlying
// Set s is modified. If passed nothing it silently returns.
func (s *Set) Add(items ...interface{}) {
if len(items) == 0 {
return
}
s.l.Lock()
defer s.l.Unlock()
for _, item := range items {
s.m[item] = keyExists
}
}
// Remove deletes the specified items from the set. The underlying Set s is
// modified. If passed nothing it silently returns.
func (s *Set) Remove(items ...interface{}) {
if len(items) == 0 {
return
}
s.l.Lock()
defer s.l.Unlock()
for _, item := range items {
delete(s.m, item)
}
}
// Pop deletes and return an item from the set. The underlying Set s is
// modified. If set is empty, nil is returned.
func (s *Set) Pop() interface{} {
s.l.RLock()
for item := range s.m {
s.l.RUnlock()
s.l.Lock()
delete(s.m, item)
s.l.Unlock()
return item
}
s.l.RUnlock()
return nil
}
// Has looks for the existence of items passed. It returns false if nothing is
// passed. For multiple items it returns true only if all of the items exist.
func (s *Set) Has(items ...interface{}) bool {
// assume checked for empty item, which not exist
if len(items) == 0 {
return false
}
s.l.RLock()
defer s.l.RUnlock()
has := true
for _, item := range items {
if _, has = s.m[item]; !has {
break
}
}
return has
}
// Size returns the number of items in a set.
func (s *Set) Size() int {
s.l.RLock()
defer s.l.RUnlock()
l := len(s.m)
return l
}
// Clear removes all items from the set.
func (s *Set) Clear() {
s.l.Lock()
defer s.l.Unlock()
s.m = make(map[interface{}]struct{})
}
// IsEqual test whether s and t are the same in size and have the same items.
func (s *Set) IsEqual(t Interface) bool {
s.l.RLock()
defer s.l.RUnlock()
// Force locking only if given set is threadsafe.
if conv, ok := t.(*Set); ok {
conv.l.RLock()
defer conv.l.RUnlock()
}
// return false if they are no the same size
if sameSize := len(s.m) == t.Size(); !sameSize {
return false
}
equal := true
t.Each(func(item interface{}) bool {
_, equal = s.m[item]
return equal // if false, Each() will end
})
return equal
}
// IsSubset tests whether t is a subset of s.
func (s *Set) IsSubset(t Interface) (subset bool) {
s.l.RLock()
defer s.l.RUnlock()
subset = true
t.Each(func(item interface{}) bool {
_, subset = s.m[item]
return subset
})
return
}
// Each traverses the items in the Set, calling the provided function for each
// set member. Traversal will continue until all items in the Set have been
// visited, or if the closure returns false.
func (s *Set) Each(f func(item interface{}) bool) {
s.l.RLock()
defer s.l.RUnlock()
for item := range s.m {
if !f(item) {
break
}
}
}
// List returns a slice of all items. There is also StringSlice() and
// IntSlice() methods for returning slices of type string or int.
func (s *Set) List() []interface{} {
s.l.RLock()
defer s.l.RUnlock()
list := make([]interface{}, 0, len(s.m))
for item := range s.m {
list = append(list, item)
}
return list
}
// Copy returns a new Set with a copy of s.
func (s *Set) Copy() Interface {
u := newTS()
for item := range s.m {
u.Add(item)
}
return u
}
// Merge is like Union, however it modifies the current set it's applied on
// with the given t set.
func (s *Set) Merge(t Interface) {
s.l.Lock()
defer s.l.Unlock()
t.Each(func(item interface{}) bool {
s.m[item] = keyExists
return true
})
}