set_nots.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package set
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. // Provides a common set baseline for both threadsafe and non-ts Sets.
  7. type set struct {
  8. m map[interface{}]struct{} // struct{} doesn't take up space
  9. lenChange bool //List 做缓存
  10. list []interface{}
  11. }
  12. // SetNonTS defines a non-thread safe set data structure.
  13. type SetNonTS struct {
  14. set
  15. }
  16. // NewNonTS creates and initializes a new non-threadsafe Set.
  17. func newNonTS() *SetNonTS {
  18. s := &SetNonTS{}
  19. s.m = make(map[interface{}]struct{}, 16)
  20. s.lenChange = false
  21. s.list = make([]interface{}, 0, 32)
  22. // Ensure interface compliance
  23. var _ Interface = s
  24. return s
  25. }
  26. // Add includes the specified items (one or more) to the set. The underlying
  27. // Set s is modified. If passed nothing it silently returns.
  28. func (s *set) Add(items ...interface{}) {
  29. if len(items) == 0 {
  30. return
  31. }
  32. for _, item := range items {
  33. if _, ok := s.m[item]; !ok {
  34. s.list = append(s.list, item)
  35. }
  36. s.m[item] = keyExists
  37. }
  38. }
  39. // Remove deletes the specified items from the set. The underlying Set s is
  40. // modified. If passed nothing it silently returns.
  41. func (s *set) Remove(items ...interface{}) {
  42. if len(items) == 0 {
  43. return
  44. }
  45. for _, item := range items {
  46. delete(s.m, item)
  47. }
  48. s.lenChange = true
  49. }
  50. // Pop deletes and return an item from the set. The underlying Set s is
  51. // modified. If set is empty, nil is returned.
  52. func (s *set) Pop() interface{} {
  53. for item := range s.m {
  54. delete(s.m, item)
  55. s.lenChange = true
  56. return item
  57. }
  58. return nil
  59. }
  60. // Has looks for the existence of items passed. It returns false if nothing is
  61. // passed. For multiple items it returns true only if all of the items exist.
  62. func (s *set) Has(items ...interface{}) bool {
  63. // assume checked for empty item, which not exist
  64. if len(items) == 0 {
  65. return false
  66. }
  67. has := true
  68. for _, item := range items {
  69. if _, has = s.m[item]; !has {
  70. break
  71. }
  72. }
  73. return has
  74. }
  75. // Size returns the number of items in a set.
  76. func (s *set) Size() int {
  77. return len(s.m)
  78. }
  79. // Clear removes all items from the set.
  80. func (s *set) Clear() {
  81. s.m = make(map[interface{}]struct{}, 16)
  82. s.lenChange = false
  83. if len(s.list) > 0 {
  84. s.list = s.list[:0]
  85. }
  86. }
  87. // IsEmpty reports whether the Set is empty.
  88. func (s *set) IsEmpty() bool {
  89. return s.Size() == 0
  90. }
  91. // IsEqual test whether s and t are the same in size and have the same items.
  92. func (s *set) IsEqual(t Interface) bool {
  93. // Force locking only if given set is threadsafe.
  94. if conv, ok := t.(*Set); ok {
  95. conv.l.RLock()
  96. defer conv.l.RUnlock()
  97. }
  98. // return false if they are no the same size
  99. if sameSize := len(s.m) == t.Size(); !sameSize {
  100. return false
  101. }
  102. equal := true
  103. t.Each(func(item interface{}) bool {
  104. _, equal = s.m[item]
  105. return equal // if false, Each() will end
  106. })
  107. return equal
  108. }
  109. // IsSubset tests whether t is a subset of s.
  110. func (s *set) IsSubset(t Interface) (subset bool) {
  111. subset = true
  112. t.Each(func(item interface{}) bool {
  113. _, subset = s.m[item]
  114. return subset
  115. })
  116. return
  117. }
  118. // IsSuperset tests whether t is a superset of s.
  119. func (s *set) IsSuperset(t Interface) bool {
  120. return t.IsSubset(s)
  121. }
  122. // Each traverses the items in the Set, calling the provided function for each
  123. // set member. Traversal will continue until all items in the Set have been
  124. // visited, or if the closure returns false.
  125. func (s *set) Each(f func(item interface{}) bool) {
  126. for item := range s.m {
  127. if !f(item) {
  128. break
  129. }
  130. }
  131. }
  132. // Copy returns a new Set with a copy of s.
  133. func (s *set) Copy() Interface {
  134. u := newNonTS()
  135. for item := range s.m {
  136. u.Add(item)
  137. }
  138. return u
  139. }
  140. func (s *set) CopyWithOut(set2 Interface, sets ...Interface) Interface {
  141. u := newNonTS()
  142. for item := range s.m {
  143. if set2.Has(item) {
  144. continue
  145. }
  146. bOk := false
  147. for _, set := range sets {
  148. if set.Has(item) {
  149. bOk = true
  150. break
  151. }
  152. }
  153. if !bOk {
  154. u.Add(item)
  155. }
  156. }
  157. return u
  158. }
  159. // String returns a string representation of s
  160. func (s *set) String() string {
  161. t := make([]string, 0, len(s.List()))
  162. for _, item := range s.List() {
  163. t = append(t, fmt.Sprintf("%v", item))
  164. }
  165. return fmt.Sprintf("[%s]", strings.Join(t, ", "))
  166. }
  167. // List returns a slice of all items. There is also StringSlice() and
  168. // IntSlice() methods for returning slices of type string or int.
  169. func (s *set) List() []interface{} {
  170. if s.lenChange {
  171. s.list = s.list[:0]
  172. for item := range s.m {
  173. s.list = append(s.list, item)
  174. }
  175. s.lenChange = false
  176. }
  177. return s.list
  178. }
  179. // Merge is like Union, however it modifies the current set it's applied on
  180. // with the given t set.
  181. func (s *set) Merge(t Interface) {
  182. t.Each(func(item interface{}) bool {
  183. s.m[item] = keyExists
  184. s.lenChange = true
  185. return true
  186. })
  187. }
  188. // it's not the opposite of Merge.
  189. // Separate removes the set items containing in t from set s. Please aware that
  190. func (s *set) Separate(t Interface) {
  191. s.Remove(t.List()...)
  192. s.lenChange = true
  193. }