github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/internal/setmatrix/setmatrix.go (about)

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