...

Source file src/edge-infra.dev/pkg/sds/lib/set/orderedset.go

Documentation: edge-infra.dev/pkg/sds/lib/set

     1  package set
     2  
     3  import (
     4  	"cmp"
     5  	"slices"
     6  )
     7  
     8  type OrderedSet[O cmp.Ordered] struct {
     9  	Set[O]
    10  	order []O
    11  }
    12  
    13  func NewOrdered[O cmp.Ordered]() *OrderedSet[O] {
    14  	return &OrderedSet[O]{
    15  		Set:   New[O](),
    16  		order: []O{},
    17  	}
    18  }
    19  
    20  // Creates an ordered set from each item in a slice.
    21  func OrderedFromSlice[S ~[]O, O cmp.Ordered](slice S) *OrderedSet[O] {
    22  	set := NewOrdered[O]()
    23  	set.Add(slice...)
    24  	return set
    25  }
    26  
    27  // Creates an ordered set from each key in a map.
    28  func OrderedFromMap[M ~map[O]V, O cmp.Ordered, V any](m M) *OrderedSet[O] {
    29  	return OrderedFromSlice(mapKeys(m))
    30  }
    31  
    32  // Convert an unordered set to ordered set.
    33  func OrderedFromSet[O cmp.Ordered](set Set[O]) *OrderedSet[O] {
    34  	return OrderedFromSlice(set.ToSlice())
    35  }
    36  
    37  // Convert the ordered set to an unordered set.
    38  func (ordered *OrderedSet[O]) ToSet() Set[O] {
    39  	return ordered.Set
    40  }
    41  
    42  // Returns an ordered slice of the members in a set.
    43  func (ordered *OrderedSet[O]) ToSlice() []O {
    44  	return ordered.order
    45  }
    46  
    47  // Adds members to the ordered set.
    48  func (ordered *OrderedSet[O]) Add(items ...O) {
    49  	for _, item := range items {
    50  		if !ordered.HasMember(item) {
    51  			ordered.Set.Add(item)
    52  			idx, _ := slices.BinarySearch(ordered.order, item)
    53  			ordered.order = slices.Insert(ordered.order, idx, item)
    54  		}
    55  	}
    56  }
    57  
    58  // Removes members from the ordered set, if they exists.
    59  func (ordered *OrderedSet[O]) Remove(items ...O) {
    60  	ordered.Set.Remove(items...)
    61  	ordered.order = slices.DeleteFunc(ordered.order, func(item O) bool {
    62  		return !ordered.HasMember(item)
    63  	})
    64  }
    65  

View as plain text