e2etest/newe2e_resource_trie.go (87 lines of code) (raw):

package e2etest import "strings" type PathTrie[T any] struct { Nodes *TrieNode[T] Sep rune } type TrieNode[T any] struct { Parent *TrieNode[T] Children map[string]*TrieNode[T] Segment string Data *T } func NewTrie[T any](Separator rune) *PathTrie[T] { return &PathTrie[T]{Sep: Separator, Nodes: createNode[T]("", nil)} } func createNode[T any](Segment string, Parent *TrieNode[T]) *TrieNode[T] { return &TrieNode[T]{Segment: Segment, Parent: Parent, Children: make(map[string]*TrieNode[T])} } func (t *PathTrie[T]) walk(path string, doCreate bool) *TrieNode[T] { currentNode := t.Nodes for len(path) > 0 { segmentLength := strings.IndexRune(path, t.Sep) if segmentLength == -1 { segmentLength = len(path) } segment := path[:segmentLength] newNode, OK := currentNode.Children[segment] if !OK { if doCreate { newNode = createNode(segment, currentNode) currentNode.Children[segment] = newNode } else { return nil } } currentNode = newNode if segmentLength == len(path) { path = "" } else { path = path[segmentLength+1:] } } return currentNode } func (t *PathTrie[T]) Insert(path string, data *T) { newNode := t.walk(path, true) newNode.Data = data } func (t *PathTrie[T]) Get(path string) *T { node := t.walk(path, false) if node == nil { return nil } return node.Data } func (t *PathTrie[T]) Remove(path string) { node := t.walk(path, false) for node.Parent != nil && node.Data == nil { childSegment := node.Segment node = node.Parent delete(node.Children, childSegment) } } type TraversalOperation uint8 const ( // TraversalOperationContinue continue traversing children TraversalOperationContinue TraversalOperation = iota // TraversalOperationStop stop traversing children TraversalOperationStop // TraversalOperationRemove remove this node from the tree and all children TraversalOperationRemove ) func (t *PathTrie[T]) Traverse(traversalFunc func(data *T) TraversalOperation) { t.Nodes.Traverse(traversalFunc) } func (n *TrieNode[T]) Traverse(traversalFunc func(data *T) TraversalOperation) { op := TraversalOperationContinue if n.Data != nil { op = traversalFunc(n.Data) } switch op { case TraversalOperationContinue: for _, v := range n.Children { v.Traverse(traversalFunc) } case TraversalOperationRemove: delete(n.Parent.Children, n.Segment) default: } }