mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
111 lines
1.8 KiB
Go
111 lines
1.8 KiB
Go
package keyseq
|
|
|
|
import (
|
|
"container/list"
|
|
)
|
|
|
|
type Trie interface {
|
|
Root() Node
|
|
GetList(KeyList) Node
|
|
Get(Key) Node
|
|
Put(KeyList, any) Node
|
|
Size() int
|
|
}
|
|
|
|
// NewTrie creates a new empty Trie for storing key sequences.
|
|
func NewTrie() Trie {
|
|
return NewTernaryTrie()
|
|
}
|
|
|
|
// Get looks up a value by key sequence path in the trie, returning nil if not found.
|
|
func Get(t Trie, k KeyList) Node {
|
|
if t == nil {
|
|
return nil
|
|
}
|
|
n := t.Root()
|
|
for _, c := range k {
|
|
n = n.Get(c)
|
|
if n == nil {
|
|
return nil
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
// Put inserts a value at the given key sequence path in the trie, creating nodes as needed.
|
|
func Put(t Trie, k KeyList, v any) Node {
|
|
if t == nil {
|
|
return nil
|
|
}
|
|
n := t.Root()
|
|
for _, c := range k {
|
|
n, _ = n.Dig(c)
|
|
}
|
|
n.SetValue(v)
|
|
return n
|
|
}
|
|
|
|
// EachDepth iterates over trie nodes in depth-first order, calling proc for each node.
|
|
func EachDepth(t Trie, proc func(Node) bool) {
|
|
if t == nil {
|
|
return
|
|
}
|
|
r := t.Root()
|
|
var f func(Node) bool
|
|
f = func(n Node) bool {
|
|
n.Each(f)
|
|
return proc(n)
|
|
}
|
|
r.Each(f)
|
|
}
|
|
|
|
// EachWidth iterates over trie nodes in breadth-first order, calling proc for each node.
|
|
func EachWidth(t Trie, proc func(Node) bool) {
|
|
if t == nil {
|
|
return
|
|
}
|
|
q := list.New()
|
|
q.PushBack(t.Root())
|
|
for q.Len() != 0 {
|
|
f := q.Front()
|
|
q.Remove(f)
|
|
t, ok := f.Value.(Node)
|
|
if !ok {
|
|
break
|
|
}
|
|
if !proc(t) {
|
|
break
|
|
}
|
|
t.Each(func(n Node) bool {
|
|
q.PushBack(n)
|
|
return true
|
|
})
|
|
}
|
|
}
|
|
|
|
type Node interface {
|
|
Get(k Key) Node
|
|
GetList(k KeyList) Node
|
|
Dig(k Key) (Node, bool)
|
|
HasChildren() bool
|
|
Size() int
|
|
Each(func(Node) bool)
|
|
RemoveAll()
|
|
|
|
Label() Key
|
|
Value() any
|
|
SetValue(v any)
|
|
}
|
|
|
|
// Children returns all child nodes of n as a slice.
|
|
func Children(n Node) []Node {
|
|
children := make([]Node, n.Size())
|
|
idx := 0
|
|
n.Each(func(n Node) bool {
|
|
children[idx] = n
|
|
idx++
|
|
return true
|
|
})
|
|
return children
|
|
}
|