mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
f969f26966
* Correct SetMatrix documentation The SetMatrix is a generic data structure, so the description should not be tight to any specific use Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com> * Service Discovery reuse name and serviceBindings deletion - Added logic to handle name reuse from different services - Moved the deletion from the serviceBindings map at the end of the rmServiceBindings body to avoid race with new services Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com> * Avoid race on network cleanup Use the locker to avoid the race between the network deletion and new endpoints being created Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com> * CleanupServiceBindings to clean the SD records Allow the cleanupServicebindings to take care of the service discovery cleanup. Also avoid to trigger the cleanup for each endpoint from an SD point of view LB and SD will be separated in the future Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com> * Addressed comments Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com> * NetworkDB deleteEntry has to happen If there is an error locally guarantee that the delete entry on network DB is still honored Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
135 lines
3 KiB
Go
135 lines
3 KiB
Go
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)
|
|
// Contains is used to verify if an element is in a set for a specific key
|
|
// 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)
|
|
// 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
|
|
Insert(key string, value interface{}) (bool, int)
|
|
// 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
|
|
Remove(key string, value interface{}) (bool, int)
|
|
// Cardinality returns the number of elements in the set for a key
|
|
// returns false if the set is not present
|
|
Cardinality(key string) (int, bool)
|
|
// String returns the string version of the set, empty otherwise
|
|
// returns false if the set is not present
|
|
String(key string) (string, bool)
|
|
// Returns all the keys in the map
|
|
Keys() []string
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|