2017-06-07 16:09:50 -04:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
mapset "github.com/deckarep/golang-set"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SetMatrix is a map of Sets
|
|
|
|
type SetMatrix interface {
|
|
|
|
// Get returns the members of the set for a specific key as a slice.
|
|
|
|
Get(key string) ([]interface{}, bool)
|
2017-06-18 08:25:58 -04:00
|
|
|
// Contains is used to verify if an element is in a set for a specific key
|
2017-06-07 16:09:50 -04:00
|
|
|
// returns true if the element is in the set
|
|
|
|
// returns true if there is a set for the key
|
|
|
|
Contains(key string, value interface{}) (bool, bool)
|
2017-06-18 08:25:58 -04:00
|
|
|
// Insert inserts the value in the set of a key
|
|
|
|
// returns true if the value is inserted (was not already in the set), false otherwise
|
|
|
|
// returns also the length of the set for the key
|
2017-06-07 16:09:50 -04:00
|
|
|
Insert(key string, value interface{}) (bool, int)
|
2017-06-18 08:25:58 -04:00
|
|
|
// Remove removes the value in the set for a specific key
|
|
|
|
// returns true if the value is deleted, false otherwise
|
|
|
|
// returns also the length of the set for the key
|
2017-06-07 16:09:50 -04:00
|
|
|
Remove(key string, value interface{}) (bool, int)
|
2017-06-18 08:25:58 -04:00
|
|
|
// Cardinality returns the number of elements in the set for a key
|
|
|
|
// returns false if the set is not present
|
2017-06-07 16:09:50 -04:00
|
|
|
Cardinality(key string) (int, bool)
|
|
|
|
// String returns the string version of the set, empty otherwise
|
2017-06-18 08:25:58 -04:00
|
|
|
// returns false if the set is not present
|
2017-06-07 16:09:50 -04:00
|
|
|
String(key string) (string, bool)
|
2017-06-18 08:25:58 -04:00
|
|
|
// Returns all the keys in the map
|
|
|
|
Keys() []string
|
2017-06-07 16:09:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
type setMatrix struct {
|
|
|
|
matrix map[string]mapset.Set
|
|
|
|
|
|
|
|
sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSetMatrix creates a new set matrix object
|
|
|
|
func NewSetMatrix() SetMatrix {
|
|
|
|
s := &setMatrix{}
|
|
|
|
s.init()
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) init() {
|
|
|
|
s.matrix = make(map[string]mapset.Set)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) Get(key string) ([]interface{}, bool) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
return nil, ok
|
|
|
|
}
|
|
|
|
return set.ToSlice(), ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) Contains(key string, value interface{}) (bool, bool) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
return false, ok
|
|
|
|
}
|
|
|
|
return set.Contains(value), ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) Insert(key string, value interface{}) (bool, int) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
s.matrix[key] = mapset.NewSet()
|
|
|
|
s.matrix[key].Add(value)
|
|
|
|
return true, 1
|
|
|
|
}
|
|
|
|
|
|
|
|
return set.Add(value), set.Cardinality()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) Remove(key string, value interface{}) (bool, int) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
return false, 0
|
|
|
|
}
|
|
|
|
|
|
|
|
var removed bool
|
|
|
|
if set.Contains(value) {
|
|
|
|
set.Remove(value)
|
|
|
|
removed = true
|
|
|
|
// If the set is empty remove it from the matrix
|
|
|
|
if set.Cardinality() == 0 {
|
|
|
|
delete(s.matrix, key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return removed, set.Cardinality()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) Cardinality(key string) (int, bool) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
return 0, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
return set.Cardinality(), ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *setMatrix) String(key string) (string, bool) {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
set, ok := s.matrix[key]
|
|
|
|
if !ok {
|
|
|
|
return "", ok
|
|
|
|
}
|
|
|
|
return set.String(), ok
|
|
|
|
}
|
2017-06-18 08:25:58 -04:00
|
|
|
|
|
|
|
func (s *setMatrix) Keys() []string {
|
|
|
|
s.Lock()
|
|
|
|
defer s.Unlock()
|
|
|
|
keys := make([]string, 0, len(s.matrix))
|
|
|
|
for k := range s.matrix {
|
|
|
|
keys = append(keys, k)
|
|
|
|
}
|
|
|
|
return keys
|
|
|
|
}
|