github.com/cloudberrydb/gpbackup@v1.0.3-0.20240118031043-5410fd45eed6/utils/set.go (about)

     1  package utils
     2  
     3  /*
     4   * This file contains an implementation of a set as a wrapper around a map[string]bool
     5   * for use in filtering lists.
     6   */
     7  
     8  /*
     9   * This set implementation can be used in one of two ways.  An "include" set
    10   * returns true if an item is in the map and false otherwise, while an "exclude"
    11   * set returns false if an item is in the map and true otherwise, so that the
    12   * set can be used for filtering on items in lists.
    13   *
    14   * The alwaysMatchesFilter variable causes MatchesFilter() to always return true
    15   * if an empty list is passed, so that it doesn't attempt to filter on anything
    16   * The isExclude variable controls whether a set is an include set or an exclude
    17   * set.
    18   */
    19  type FilterSet struct {
    20  	Set                 map[string]bool
    21  	IsExclude           bool
    22  	AlwaysMatchesFilter bool
    23  }
    24  
    25  func NewSet(list []string) *FilterSet {
    26  	newSet := FilterSet{}
    27  	newSet.Set = make(map[string]bool, len(list))
    28  	for _, item := range list {
    29  		newSet.Set[item] = true
    30  	}
    31  	return &newSet
    32  }
    33  
    34  func NewIncludeSet(list []string) *FilterSet {
    35  	newSet := NewSet(list)
    36  	(*newSet).AlwaysMatchesFilter = len(list) == 0
    37  	return newSet
    38  }
    39  
    40  func NewExcludeSet(list []string) *FilterSet {
    41  	newSet := NewSet(list)
    42  	(*newSet).AlwaysMatchesFilter = len(list) == 0
    43  	(*newSet).IsExclude = true
    44  	return newSet
    45  }
    46  
    47  func (s *FilterSet) MatchesFilter(item string) bool {
    48  	if s.AlwaysMatchesFilter {
    49  		return true
    50  	}
    51  	_, matches := s.Set[item]
    52  	if s.IsExclude {
    53  		return !matches
    54  	}
    55  	return matches
    56  }
    57  
    58  func (s *FilterSet) Length() int {
    59  	return len(s.Set)
    60  }
    61  
    62  func (s *FilterSet) Equals(s1 *FilterSet) bool {
    63  	if s.Length() != s1.Length() {
    64  		return false
    65  	}
    66  
    67  	for k := range s.Set {
    68  		if _, ok := s1.Set[k]; !ok {
    69  			return false
    70  		}
    71  	}
    72  	return true
    73  }