setmatrix.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package setmatrix
  2. import (
  3. "sync"
  4. mapset "github.com/deckarep/golang-set"
  5. )
  6. // SetMatrix is a map of Sets.
  7. type SetMatrix struct {
  8. matrix map[string]mapset.Set
  9. mu sync.Mutex
  10. }
  11. // NewSetMatrix creates a new set matrix object.
  12. func NewSetMatrix() *SetMatrix {
  13. s := &SetMatrix{}
  14. s.init()
  15. return s
  16. }
  17. func (s *SetMatrix) init() {
  18. s.matrix = make(map[string]mapset.Set)
  19. }
  20. // Get returns the members of the set for a specific key as a slice.
  21. func (s *SetMatrix) Get(key string) ([]interface{}, bool) {
  22. s.mu.Lock()
  23. defer s.mu.Unlock()
  24. set, ok := s.matrix[key]
  25. if !ok {
  26. return nil, ok
  27. }
  28. return set.ToSlice(), ok
  29. }
  30. // Contains is used to verify if an element is in a set for a specific key.
  31. func (s *SetMatrix) Contains(key string, value interface{}) (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. // Insert inserts the value in the set of a key and returns whether the value is
  41. // inserted (was not already in the set) and the number of elements in the set.
  42. func (s *SetMatrix) Insert(key string, value interface{}) (insetrted bool, cardinality int) {
  43. s.mu.Lock()
  44. defer s.mu.Unlock()
  45. set, ok := s.matrix[key]
  46. if !ok {
  47. s.matrix[key] = mapset.NewSet()
  48. s.matrix[key].Add(value)
  49. return true, 1
  50. }
  51. return set.Add(value), set.Cardinality()
  52. }
  53. // Remove removes the value in the set for a specific key.
  54. func (s *SetMatrix) Remove(key string, value interface{}) (removed bool, cardinality int) {
  55. s.mu.Lock()
  56. defer s.mu.Unlock()
  57. set, ok := s.matrix[key]
  58. if !ok {
  59. return false, 0
  60. }
  61. if set.Contains(value) {
  62. set.Remove(value)
  63. removed = true
  64. // If the set is empty remove it from the matrix
  65. if set.Cardinality() == 0 {
  66. delete(s.matrix, key)
  67. }
  68. }
  69. return removed, set.Cardinality()
  70. }
  71. // Cardinality returns the number of elements in the set for a key.
  72. func (s *SetMatrix) Cardinality(key string) (cardinality int, ok bool) {
  73. s.mu.Lock()
  74. defer s.mu.Unlock()
  75. set, ok := s.matrix[key]
  76. if !ok {
  77. return 0, ok
  78. }
  79. return set.Cardinality(), ok
  80. }
  81. // String returns the string version of the set.
  82. // The empty string is returned if there is no set for key.
  83. func (s *SetMatrix) String(key string) (v string, ok bool) {
  84. s.mu.Lock()
  85. defer s.mu.Unlock()
  86. set, ok := s.matrix[key]
  87. if !ok {
  88. return "", ok
  89. }
  90. return set.String(), ok
  91. }
  92. // Keys returns all the keys in the map.
  93. func (s *SetMatrix) Keys() []string {
  94. s.mu.Lock()
  95. defer s.mu.Unlock()
  96. keys := make([]string, 0, len(s.matrix))
  97. for k := range s.matrix {
  98. keys = append(keys, k)
  99. }
  100. return keys
  101. }