8 // WalkFn is used when walking the tree. Takes a
9 // key and value, returning if iteration should
11 type WalkFn func(k []byte, v interface{}) bool
13 // leafNode is used to represent a value
14 type leafNode struct {
19 // edge is used to represent an edge node
25 // Node is an immutable node in the radix tree
27 // leaf is used to store possible leaf
30 // prefix is the common prefix we ignore
33 // Edges should be stored in-order for iteration.
34 // We avoid a fully materialized slice to save memory,
35 // since in most cases we expect to be sparse
39 func (n *Node) isLeaf() bool {
43 func (n *Node) addEdge(e edge) {
45 idx := sort.Search(num, func(i int) bool {
46 return n.edges[i].label >= e.label
48 n.edges = append(n.edges, e)
50 copy(n.edges[idx+1:], n.edges[idx:num])
55 func (n *Node) replaceEdge(e edge) {
57 idx := sort.Search(num, func(i int) bool {
58 return n.edges[i].label >= e.label
60 if idx < num && n.edges[idx].label == e.label {
61 n.edges[idx].node = e.node
64 panic("replacing missing edge")
67 func (n *Node) getEdge(label byte) (int, *Node) {
69 idx := sort.Search(num, func(i int) bool {
70 return n.edges[i].label >= label
72 if idx < num && n.edges[idx].label == label {
73 return idx, n.edges[idx].node
78 func (n *Node) delEdge(label byte) {
80 idx := sort.Search(num, func(i int) bool {
81 return n.edges[i].label >= label
83 if idx < num && n.edges[idx].label == label {
84 copy(n.edges[idx:], n.edges[idx+1:])
85 n.edges[len(n.edges)-1] = edge{}
86 n.edges = n.edges[:len(n.edges)-1]
90 func (n *Node) mergeChild() {
93 n.prefix = concat(n.prefix, child.prefix)
94 if child.leaf != nil {
95 n.leaf = new(leafNode)
100 if len(child.edges) != 0 {
101 n.edges = make([]edge, len(child.edges))
102 copy(n.edges, child.edges)
108 func (n *Node) Get(k []byte) (interface{}, bool) {
111 // Check for key exhaution
112 if len(search) == 0 {
114 return n.leaf.val, true
120 _, n = n.getEdge(search[0])
125 // Consume the search prefix
126 if bytes.HasPrefix(search, n.prefix) {
127 search = search[len(n.prefix):]
135 // LongestPrefix is like Get, but instead of an
136 // exact match, it will return the longest prefix match.
137 func (n *Node) LongestPrefix(k []byte) ([]byte, interface{}, bool) {
141 // Look for a leaf node
146 // Check for key exhaution
147 if len(search) == 0 {
152 _, n = n.getEdge(search[0])
157 // Consume the search prefix
158 if bytes.HasPrefix(search, n.prefix) {
159 search = search[len(n.prefix):]
165 return last.key, last.val, true
167 return nil, nil, false
170 // Minimum is used to return the minimum value in the tree
171 func (n *Node) Minimum() ([]byte, interface{}, bool) {
174 return n.leaf.key, n.leaf.val, true
176 if len(n.edges) > 0 {
182 return nil, nil, false
185 // Maximum is used to return the maximum value in the tree
186 func (n *Node) Maximum() ([]byte, interface{}, bool) {
188 if num := len(n.edges); num > 0 {
189 n = n.edges[num-1].node
193 return n.leaf.key, n.leaf.val, true
198 return nil, nil, false
201 // Iterator is used to return an iterator at
202 // the given node to walk the tree
203 func (n *Node) Iterator() *Iterator {
204 return &Iterator{node: n}
207 // Walk is used to walk the tree
208 func (n *Node) Walk(fn WalkFn) {
212 // WalkPrefix is used to walk the tree under a prefix
213 func (n *Node) WalkPrefix(prefix []byte, fn WalkFn) {
216 // Check for key exhaution
217 if len(search) == 0 {
223 _, n = n.getEdge(search[0])
228 // Consume the search prefix
229 if bytes.HasPrefix(search, n.prefix) {
230 search = search[len(n.prefix):]
232 } else if bytes.HasPrefix(n.prefix, search) {
233 // Child may be under our search prefix
242 // WalkPath is used to walk the tree, but only visiting nodes
243 // from the root down to a given leaf. Where WalkPrefix walks
244 // all the entries *under* the given prefix, this walks the
245 // entries *above* the given prefix.
246 func (n *Node) WalkPath(path []byte, fn WalkFn) {
249 // Visit the leaf values if any
250 if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
254 // Check for key exhaution
255 if len(search) == 0 {
260 _, n = n.getEdge(search[0])
265 // Consume the search prefix
266 if bytes.HasPrefix(search, n.prefix) {
267 search = search[len(n.prefix):]
274 // recursiveWalk is used to do a pre-order walk of a node
275 // recursively. Returns true if the walk should be aborted
276 func recursiveWalk(n *Node, fn WalkFn) bool {
277 // Visit the leaf values if any
278 if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
282 // Recurse on the children
283 for _, e := range n.edges {
284 if recursiveWalk(e.node, fn) {