gset_any_set.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. // Package gset provides kinds of concurrent-safe/unsafe sets.
  7. package gset
  8. import (
  9. "bytes"
  10. "github.com/gogf/gf/internal/json"
  11. "github.com/gogf/gf/internal/rwmutex"
  12. "github.com/gogf/gf/text/gstr"
  13. "github.com/gogf/gf/util/gconv"
  14. )
  15. type Set struct {
  16. mu rwmutex.RWMutex
  17. data map[interface{}]struct{}
  18. }
  19. // New create and returns a new set, which contains un-repeated items.
  20. // The parameter <safe> is used to specify whether using set in concurrent-safety,
  21. // which is false in default.
  22. func New(safe ...bool) *Set {
  23. return NewSet(safe...)
  24. }
  25. // See New.
  26. func NewSet(safe ...bool) *Set {
  27. return &Set{
  28. data: make(map[interface{}]struct{}),
  29. mu: rwmutex.Create(safe...),
  30. }
  31. }
  32. // NewFrom returns a new set from <items>.
  33. // Parameter <items> can be either a variable of any type, or a slice.
  34. func NewFrom(items interface{}, safe ...bool) *Set {
  35. m := make(map[interface{}]struct{})
  36. for _, v := range gconv.Interfaces(items) {
  37. m[v] = struct{}{}
  38. }
  39. return &Set{
  40. data: m,
  41. mu: rwmutex.Create(safe...),
  42. }
  43. }
  44. // Iterator iterates the set readonly with given callback function <f>,
  45. // if <f> returns true then continue iterating; or false to stop.
  46. func (set *Set) Iterator(f func(v interface{}) bool) {
  47. set.mu.RLock()
  48. defer set.mu.RUnlock()
  49. for k, _ := range set.data {
  50. if !f(k) {
  51. break
  52. }
  53. }
  54. }
  55. // Add adds one or multiple items to the set.
  56. func (set *Set) Add(items ...interface{}) {
  57. set.mu.Lock()
  58. if set.data == nil {
  59. set.data = make(map[interface{}]struct{})
  60. }
  61. for _, v := range items {
  62. set.data[v] = struct{}{}
  63. }
  64. set.mu.Unlock()
  65. }
  66. // AddIfNotExist checks whether item exists in the set,
  67. // it adds the item to set and returns true if it does not exists in the set,
  68. // or else it does nothing and returns false.
  69. //
  70. // Note that, if <item> is nil, it does nothing and returns false.
  71. func (set *Set) AddIfNotExist(item interface{}) bool {
  72. if item == nil {
  73. return false
  74. }
  75. if !set.Contains(item) {
  76. set.mu.Lock()
  77. defer set.mu.Unlock()
  78. if set.data == nil {
  79. set.data = make(map[interface{}]struct{})
  80. }
  81. if _, ok := set.data[item]; !ok {
  82. set.data[item] = struct{}{}
  83. return true
  84. }
  85. }
  86. return false
  87. }
  88. // AddIfNotExistFunc checks whether item exists in the set,
  89. // it adds the item to set and returns true if it does not exists in the set and
  90. // function <f> returns true, or else it does nothing and returns false.
  91. //
  92. // Note that, if <item> is nil, it does nothing and returns false. The function <f>
  93. // is executed without writing lock.
  94. func (set *Set) AddIfNotExistFunc(item interface{}, f func() bool) bool {
  95. if item == nil {
  96. return false
  97. }
  98. if !set.Contains(item) {
  99. if f() {
  100. set.mu.Lock()
  101. defer set.mu.Unlock()
  102. if set.data == nil {
  103. set.data = make(map[interface{}]struct{})
  104. }
  105. if _, ok := set.data[item]; !ok {
  106. set.data[item] = struct{}{}
  107. return true
  108. }
  109. }
  110. }
  111. return false
  112. }
  113. // AddIfNotExistFunc checks whether item exists in the set,
  114. // it adds the item to set and returns true if it does not exists in the set and
  115. // function <f> returns true, or else it does nothing and returns false.
  116. //
  117. // Note that, if <item> is nil, it does nothing and returns false. The function <f>
  118. // is executed within writing lock.
  119. func (set *Set) AddIfNotExistFuncLock(item interface{}, f func() bool) bool {
  120. if item == nil {
  121. return false
  122. }
  123. if !set.Contains(item) {
  124. set.mu.Lock()
  125. defer set.mu.Unlock()
  126. if set.data == nil {
  127. set.data = make(map[interface{}]struct{})
  128. }
  129. if f() {
  130. if _, ok := set.data[item]; !ok {
  131. set.data[item] = struct{}{}
  132. return true
  133. }
  134. }
  135. }
  136. return false
  137. }
  138. // Contains checks whether the set contains <item>.
  139. func (set *Set) Contains(item interface{}) bool {
  140. var ok bool
  141. set.mu.RLock()
  142. if set.data != nil {
  143. _, ok = set.data[item]
  144. }
  145. set.mu.RUnlock()
  146. return ok
  147. }
  148. // Remove deletes <item> from set.
  149. func (set *Set) Remove(item interface{}) {
  150. set.mu.Lock()
  151. if set.data != nil {
  152. delete(set.data, item)
  153. }
  154. set.mu.Unlock()
  155. }
  156. // Size returns the size of the set.
  157. func (set *Set) Size() int {
  158. set.mu.RLock()
  159. l := len(set.data)
  160. set.mu.RUnlock()
  161. return l
  162. }
  163. // Clear deletes all items of the set.
  164. func (set *Set) Clear() {
  165. set.mu.Lock()
  166. set.data = make(map[interface{}]struct{})
  167. set.mu.Unlock()
  168. }
  169. // Slice returns the a of items of the set as slice.
  170. func (set *Set) Slice() []interface{} {
  171. set.mu.RLock()
  172. var (
  173. i = 0
  174. ret = make([]interface{}, len(set.data))
  175. )
  176. for item := range set.data {
  177. ret[i] = item
  178. i++
  179. }
  180. set.mu.RUnlock()
  181. return ret
  182. }
  183. // Join joins items with a string <glue>.
  184. func (set *Set) Join(glue string) string {
  185. set.mu.RLock()
  186. defer set.mu.RUnlock()
  187. if len(set.data) == 0 {
  188. return ""
  189. }
  190. var (
  191. l = len(set.data)
  192. i = 0
  193. buffer = bytes.NewBuffer(nil)
  194. )
  195. for k, _ := range set.data {
  196. buffer.WriteString(gconv.String(k))
  197. if i != l-1 {
  198. buffer.WriteString(glue)
  199. }
  200. i++
  201. }
  202. return buffer.String()
  203. }
  204. // String returns items as a string, which implements like json.Marshal does.
  205. func (set *Set) String() string {
  206. set.mu.RLock()
  207. defer set.mu.RUnlock()
  208. var (
  209. s = ""
  210. l = len(set.data)
  211. i = 0
  212. buffer = bytes.NewBuffer(nil)
  213. )
  214. buffer.WriteByte('[')
  215. for k, _ := range set.data {
  216. s = gconv.String(k)
  217. if gstr.IsNumeric(s) {
  218. buffer.WriteString(s)
  219. } else {
  220. buffer.WriteString(`"` + gstr.QuoteMeta(s, `"\`) + `"`)
  221. }
  222. if i != l-1 {
  223. buffer.WriteByte(',')
  224. }
  225. i++
  226. }
  227. buffer.WriteByte(']')
  228. return buffer.String()
  229. }
  230. // LockFunc locks writing with callback function <f>.
  231. func (set *Set) LockFunc(f func(m map[interface{}]struct{})) {
  232. set.mu.Lock()
  233. defer set.mu.Unlock()
  234. f(set.data)
  235. }
  236. // RLockFunc locks reading with callback function <f>.
  237. func (set *Set) RLockFunc(f func(m map[interface{}]struct{})) {
  238. set.mu.RLock()
  239. defer set.mu.RUnlock()
  240. f(set.data)
  241. }
  242. // Equal checks whether the two sets equal.
  243. func (set *Set) Equal(other *Set) bool {
  244. if set == other {
  245. return true
  246. }
  247. set.mu.RLock()
  248. defer set.mu.RUnlock()
  249. other.mu.RLock()
  250. defer other.mu.RUnlock()
  251. if len(set.data) != len(other.data) {
  252. return false
  253. }
  254. for key := range set.data {
  255. if _, ok := other.data[key]; !ok {
  256. return false
  257. }
  258. }
  259. return true
  260. }
  261. // IsSubsetOf checks whether the current set is a sub-set of <other>.
  262. func (set *Set) IsSubsetOf(other *Set) bool {
  263. if set == other {
  264. return true
  265. }
  266. set.mu.RLock()
  267. defer set.mu.RUnlock()
  268. other.mu.RLock()
  269. defer other.mu.RUnlock()
  270. for key := range set.data {
  271. if _, ok := other.data[key]; !ok {
  272. return false
  273. }
  274. }
  275. return true
  276. }
  277. // Union returns a new set which is the union of <set> and <others>.
  278. // Which means, all the items in <newSet> are in <set> or in <others>.
  279. func (set *Set) Union(others ...*Set) (newSet *Set) {
  280. newSet = NewSet()
  281. set.mu.RLock()
  282. defer set.mu.RUnlock()
  283. for _, other := range others {
  284. if set != other {
  285. other.mu.RLock()
  286. }
  287. for k, v := range set.data {
  288. newSet.data[k] = v
  289. }
  290. if set != other {
  291. for k, v := range other.data {
  292. newSet.data[k] = v
  293. }
  294. }
  295. if set != other {
  296. other.mu.RUnlock()
  297. }
  298. }
  299. return
  300. }
  301. // Diff returns a new set which is the difference set from <set> to <others>.
  302. // Which means, all the items in <newSet> are in <set> but not in <others>.
  303. func (set *Set) Diff(others ...*Set) (newSet *Set) {
  304. newSet = NewSet()
  305. set.mu.RLock()
  306. defer set.mu.RUnlock()
  307. for _, other := range others {
  308. if set == other {
  309. continue
  310. }
  311. other.mu.RLock()
  312. for k, v := range set.data {
  313. if _, ok := other.data[k]; !ok {
  314. newSet.data[k] = v
  315. }
  316. }
  317. other.mu.RUnlock()
  318. }
  319. return
  320. }
  321. // Intersect returns a new set which is the intersection from <set> to <others>.
  322. // Which means, all the items in <newSet> are in <set> and also in <others>.
  323. func (set *Set) Intersect(others ...*Set) (newSet *Set) {
  324. newSet = NewSet()
  325. set.mu.RLock()
  326. defer set.mu.RUnlock()
  327. for _, other := range others {
  328. if set != other {
  329. other.mu.RLock()
  330. }
  331. for k, v := range set.data {
  332. if _, ok := other.data[k]; ok {
  333. newSet.data[k] = v
  334. }
  335. }
  336. if set != other {
  337. other.mu.RUnlock()
  338. }
  339. }
  340. return
  341. }
  342. // Complement returns a new set which is the complement from <set> to <full>.
  343. // Which means, all the items in <newSet> are in <full> and not in <set>.
  344. //
  345. // It returns the difference between <full> and <set>
  346. // if the given set <full> is not the full set of <set>.
  347. func (set *Set) Complement(full *Set) (newSet *Set) {
  348. newSet = NewSet()
  349. set.mu.RLock()
  350. defer set.mu.RUnlock()
  351. if set != full {
  352. full.mu.RLock()
  353. defer full.mu.RUnlock()
  354. }
  355. for k, v := range full.data {
  356. if _, ok := set.data[k]; !ok {
  357. newSet.data[k] = v
  358. }
  359. }
  360. return
  361. }
  362. // Merge adds items from <others> sets into <set>.
  363. func (set *Set) Merge(others ...*Set) *Set {
  364. set.mu.Lock()
  365. defer set.mu.Unlock()
  366. for _, other := range others {
  367. if set != other {
  368. other.mu.RLock()
  369. }
  370. for k, v := range other.data {
  371. set.data[k] = v
  372. }
  373. if set != other {
  374. other.mu.RUnlock()
  375. }
  376. }
  377. return set
  378. }
  379. // Sum sums items.
  380. // Note: The items should be converted to int type,
  381. // or you'd get a result that you unexpected.
  382. func (set *Set) Sum() (sum int) {
  383. set.mu.RLock()
  384. defer set.mu.RUnlock()
  385. for k, _ := range set.data {
  386. sum += gconv.Int(k)
  387. }
  388. return
  389. }
  390. // Pops randomly pops an item from set.
  391. func (set *Set) Pop() interface{} {
  392. set.mu.Lock()
  393. defer set.mu.Unlock()
  394. for k, _ := range set.data {
  395. delete(set.data, k)
  396. return k
  397. }
  398. return nil
  399. }
  400. // Pops randomly pops <size> items from set.
  401. // It returns all items if size == -1.
  402. func (set *Set) Pops(size int) []interface{} {
  403. set.mu.Lock()
  404. defer set.mu.Unlock()
  405. if size > len(set.data) || size == -1 {
  406. size = len(set.data)
  407. }
  408. if size <= 0 {
  409. return nil
  410. }
  411. index := 0
  412. array := make([]interface{}, size)
  413. for k, _ := range set.data {
  414. delete(set.data, k)
  415. array[index] = k
  416. index++
  417. if index == size {
  418. break
  419. }
  420. }
  421. return array
  422. }
  423. // Walk applies a user supplied function <f> to every item of set.
  424. func (set *Set) Walk(f func(item interface{}) interface{}) *Set {
  425. set.mu.Lock()
  426. defer set.mu.Unlock()
  427. m := make(map[interface{}]struct{}, len(set.data))
  428. for k, v := range set.data {
  429. m[f(k)] = v
  430. }
  431. set.data = m
  432. return set
  433. }
  434. // MarshalJSON implements the interface MarshalJSON for json.Marshal.
  435. func (set *Set) MarshalJSON() ([]byte, error) {
  436. return json.Marshal(set.Slice())
  437. }
  438. // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
  439. func (set *Set) UnmarshalJSON(b []byte) error {
  440. set.mu.Lock()
  441. defer set.mu.Unlock()
  442. if set.data == nil {
  443. set.data = make(map[interface{}]struct{})
  444. }
  445. var array []interface{}
  446. if err := json.Unmarshal(b, &array); err != nil {
  447. return err
  448. }
  449. for _, v := range array {
  450. set.data[v] = struct{}{}
  451. }
  452. return nil
  453. }
  454. // UnmarshalValue is an interface implement which sets any type of value for set.
  455. func (set *Set) UnmarshalValue(value interface{}) (err error) {
  456. set.mu.Lock()
  457. defer set.mu.Unlock()
  458. if set.data == nil {
  459. set.data = make(map[interface{}]struct{})
  460. }
  461. var array []interface{}
  462. switch value.(type) {
  463. case string, []byte:
  464. err = json.Unmarshal(gconv.Bytes(value), &array)
  465. default:
  466. array = gconv.SliceAny(value)
  467. }
  468. for _, v := range array {
  469. set.data[v] = struct{}{}
  470. }
  471. return
  472. }