github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/internal/setmatrix/setmatrix.go (about) 1 package setmatrix 2 3 import ( 4 "sync" 5 6 mapset "github.com/deckarep/golang-set/v2" 7 ) 8 9 // SetMatrix is a map of Sets. 10 // The zero value is an empty set matrix ready to use. 11 // 12 // SetMatrix values are safe for concurrent use. 13 type SetMatrix[T comparable] struct { 14 matrix map[string]mapset.Set[T] 15 16 mu sync.Mutex 17 } 18 19 // Get returns the members of the set for a specific key as a slice. 20 func (s *SetMatrix[T]) Get(key string) ([]T, bool) { 21 s.mu.Lock() 22 defer s.mu.Unlock() 23 set, ok := s.matrix[key] 24 if !ok { 25 return nil, ok 26 } 27 return set.ToSlice(), ok 28 } 29 30 // Contains is used to verify if an element is in a set for a specific key. 31 func (s *SetMatrix[T]) Contains(key string, value T) (containsElement, setExists bool) { 32 s.mu.Lock() 33 defer s.mu.Unlock() 34 set, ok := s.matrix[key] 35 if !ok { 36 return false, ok 37 } 38 return set.Contains(value), ok 39 } 40 41 // Insert inserts the value in the set of a key and returns whether the value is 42 // inserted (was not already in the set) and the number of elements in the set. 43 func (s *SetMatrix[T]) Insert(key string, value T) (inserted bool, cardinality int) { 44 s.mu.Lock() 45 defer s.mu.Unlock() 46 set, ok := s.matrix[key] 47 if !ok { 48 if s.matrix == nil { 49 s.matrix = make(map[string]mapset.Set[T]) 50 } 51 s.matrix[key] = mapset.NewThreadUnsafeSet(value) 52 return true, 1 53 } 54 55 return set.Add(value), set.Cardinality() 56 } 57 58 // Remove removes the value in the set for a specific key. 59 func (s *SetMatrix[T]) Remove(key string, value T) (removed bool, cardinality int) { 60 s.mu.Lock() 61 defer s.mu.Unlock() 62 set, ok := s.matrix[key] 63 if !ok { 64 return false, 0 65 } 66 67 if set.Contains(value) { 68 set.Remove(value) 69 removed = true 70 // If the set is empty remove it from the matrix 71 if set.Cardinality() == 0 { 72 delete(s.matrix, key) 73 } 74 } 75 76 return removed, set.Cardinality() 77 } 78 79 // Cardinality returns the number of elements in the set for a key. 80 func (s *SetMatrix[T]) Cardinality(key string) (cardinality int, ok bool) { 81 s.mu.Lock() 82 defer s.mu.Unlock() 83 set, ok := s.matrix[key] 84 if !ok { 85 return 0, ok 86 } 87 88 return set.Cardinality(), ok 89 } 90 91 // String returns the string version of the set. 92 // The empty string is returned if there is no set for key. 93 func (s *SetMatrix[T]) String(key string) (v string, ok bool) { 94 s.mu.Lock() 95 defer s.mu.Unlock() 96 set, ok := s.matrix[key] 97 if !ok { 98 return "", ok 99 } 100 return set.String(), ok 101 } 102 103 // Keys returns all the keys in the map. 104 func (s *SetMatrix[T]) Keys() []string { 105 s.mu.Lock() 106 defer s.mu.Unlock() 107 keys := make([]string, 0, len(s.matrix)) 108 for k := range s.matrix { 109 keys = append(keys, k) 110 } 111 return keys 112 }