mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-20 15:31:24 +02:00
feat: trie implementation
This commit is contained in:
54
internal/utils/trie/node.go
Normal file
54
internal/utils/trie/node.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package trie
|
||||
|
||||
import (
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
key string
|
||||
children *xsync.MapOf[string, *Node] // lock-free map which allows concurrent access
|
||||
value AnyValue // only end nodes have values
|
||||
}
|
||||
|
||||
func mayPrefix(key, part string) string {
|
||||
if key == "" {
|
||||
return part
|
||||
}
|
||||
return key + "." + part
|
||||
}
|
||||
|
||||
func (node *Node) newChild(part string) *Node {
|
||||
return &Node{
|
||||
key: mayPrefix(node.key, part),
|
||||
children: xsync.NewMapOf[string, *Node](),
|
||||
}
|
||||
}
|
||||
|
||||
func (node *Node) Get(key *Key) (any, bool) {
|
||||
for _, seg := range key.segments {
|
||||
child, ok := node.children.Load(seg)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
node = child
|
||||
}
|
||||
v := node.value.Load()
|
||||
if v == nil {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
}
|
||||
|
||||
func (node *Node) loadOrStore(key *Key, newFunc func() any) *Node {
|
||||
for i, seg := range key.segments {
|
||||
child, _ := node.children.LoadOrCompute(seg, func() *Node {
|
||||
newNode := node.newChild(seg)
|
||||
if i == len(key.segments)-1 {
|
||||
newNode.value.Store(newFunc())
|
||||
}
|
||||
return newNode
|
||||
})
|
||||
node = child
|
||||
}
|
||||
return node
|
||||
}
|
||||
Reference in New Issue
Block a user