github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/internal/setmatrix/setmatrix.go (about) 1 package setmatrix 2 3 import ( 4 "sync" 5 6 mapset "github.com/deckarep/golang-set" 7 ) 8 9 // SetMatrix is a map of Sets 10 type SetMatrix interface { 11 // Get returns the members of the set for a specific key as a slice. 12 Get(key string) ([]interface{}, bool) 13 // Contains is used to verify if an element is in a set for a specific key 14 // returns true if the element is in the set 15 // returns true if there is a set for the key 16 Contains(key string, value interface{}) (bool, bool) 17 // Insert inserts the value in the set of a key 18 // returns true if the value is inserted (was not already in the set), false otherwise 19 // returns also the length of the set for the key 20 Insert(key string, value interface{}) (bool, int) 21 // Remove removes the value in the set for a specific key 22 // returns true if the value is deleted, false otherwise 23 // returns also the length of the set for the key 24 Remove(key string, value interface{}) (bool, int) 25 // Cardinality returns the number of elements in the set for a key 26 // returns false if the set is not present 27 Cardinality(key string) (int, bool) 28 // String returns the string version of the set, empty otherwise 29 // returns false if the set is not present 30 String(key string) (string, bool) 31 // Returns all the keys in the map 32 Keys() []string 33 } 34 35 type setMatrix struct { 36 matrix map[string]mapset.Set 37 38 sync.Mutex 39 } 40 41 // NewSetMatrix creates a new set matrix object 42 func NewSetMatrix() SetMatrix { 43 s := &setMatrix{} 44 s.init() 45 return s 46 } 47 48 func (s *setMatrix) init() { 49 s.matrix = make(map[string]mapset.Set) 50 } 51 52 func (s *setMatrix) Get(key string) ([]interface{}, bool) { 53 s.Lock() 54 defer s.Unlock() 55 set, ok := s.matrix[key] 56 if !ok { 57 return nil, ok 58 } 59 return set.ToSlice(), ok 60 } 61 62 func (s *setMatrix) Contains(key string, value interface{}) (bool, bool) { 63 s.Lock() 64 defer s.Unlock() 65 set, ok := s.matrix[key] 66 if !ok { 67 return false, ok 68 } 69 return set.Contains(value), ok 70 } 71 72 func (s *setMatrix) Insert(key string, value interface{}) (bool, int) { 73 s.Lock() 74 defer s.Unlock() 75 set, ok := s.matrix[key] 76 if !ok { 77 s.matrix[key] = mapset.NewSet() 78 s.matrix[key].Add(value) 79 return true, 1 80 } 81 82 return set.Add(value), set.Cardinality() 83 } 84 85 func (s *setMatrix) Remove(key string, value interface{}) (bool, int) { 86 s.Lock() 87 defer s.Unlock() 88 set, ok := s.matrix[key] 89 if !ok { 90 return false, 0 91 } 92 93 var removed bool 94 if set.Contains(value) { 95 set.Remove(value) 96 removed = true 97 // If the set is empty remove it from the matrix 98 if set.Cardinality() == 0 { 99 delete(s.matrix, key) 100 } 101 } 102 103 return removed, set.Cardinality() 104 } 105 106 func (s *setMatrix) Cardinality(key string) (int, bool) { 107 s.Lock() 108 defer s.Unlock() 109 set, ok := s.matrix[key] 110 if !ok { 111 return 0, ok 112 } 113 114 return set.Cardinality(), ok 115 } 116 117 func (s *setMatrix) String(key string) (string, bool) { 118 s.Lock() 119 defer s.Unlock() 120 set, ok := s.matrix[key] 121 if !ok { 122 return "", ok 123 } 124 return set.String(), ok 125 } 126 127 func (s *setMatrix) Keys() []string { 128 s.Lock() 129 defer s.Unlock() 130 keys := make([]string, 0, len(s.matrix)) 131 for k := range s.matrix { 132 keys = append(keys, k) 133 } 134 return keys 135 }