8 // WalkFn is used when walking the tree. Takes a
9 // key and value, returning if iteration should
11 type WalkFn func(s string, v interface{}) bool
13 // leafNode is used to represent a value
14 type leafNode struct {
19 // edge is used to represent an edge node
26 // leaf is used to store possible leaf
29 // prefix is the common prefix we ignore
32 // Edges should be stored in-order for iteration.
33 // We avoid a fully materialized slice to save memory,
34 // since in most cases we expect to be sparse
38 func (n *node) isLeaf() bool {
42 func (n *node) addEdge(e edge) {
43 n.edges = append(n.edges, e)
47 func (n *node) updateEdge(label byte, node *node) {
49 idx := sort.Search(num, func(i int) bool {
50 return n.edges[i].label >= label
52 if idx < num && n.edges[idx].label == label {
53 n.edges[idx].node = node
56 panic("replacing missing edge")
59 func (n *node) getEdge(label byte) *node {
61 idx := sort.Search(num, func(i int) bool {
62 return n.edges[i].label >= label
64 if idx < num && n.edges[idx].label == label {
65 return n.edges[idx].node
70 func (n *node) delEdge(label byte) {
72 idx := sort.Search(num, func(i int) bool {
73 return n.edges[i].label >= label
75 if idx < num && n.edges[idx].label == label {
76 copy(n.edges[idx:], n.edges[idx+1:])
77 n.edges[len(n.edges)-1] = edge{}
78 n.edges = n.edges[:len(n.edges)-1]
84 func (e edges) Len() int {
88 func (e edges) Less(i, j int) bool {
89 return e[i].label < e[j].label
92 func (e edges) Swap(i, j int) {
93 e[i], e[j] = e[j], e[i]
96 func (e edges) Sort() {
100 // Tree implements a radix tree. This can be treated as a
101 // Dictionary abstract data type. The main advantage over
102 // a standard hash map is prefix-based lookups and
103 // ordered iteration,
109 // New returns an empty Tree
111 return NewFromMap(nil)
114 // NewFromMap returns a new tree containing the keys
115 // from an existing map
116 func NewFromMap(m map[string]interface{}) *Tree {
117 t := &Tree{root: &node{}}
118 for k, v := range m {
124 // Len is used to return the number of elements in the tree
125 func (t *Tree) Len() int {
129 // longestPrefix finds the length of the shared prefix
131 func longestPrefix(k1, k2 string) int {
133 if l := len(k2); l < max {
137 for i = 0; i < max; i++ {
145 // Insert is used to add a newentry or update
146 // an existing entry. Returns if updated.
147 func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
152 // Handle key exhaution
153 if len(search) == 0 {
170 n = n.getEdge(search[0])
172 // No edge, create one
189 // Determine longest prefix of the search key on match
190 commonPrefix := longestPrefix(search, n.prefix)
191 if commonPrefix == len(n.prefix) {
192 search = search[commonPrefix:]
199 prefix: search[:commonPrefix],
201 parent.updateEdge(search[0], child)
203 // Restore the existing node
205 label: n.prefix[commonPrefix],
208 n.prefix = n.prefix[commonPrefix:]
210 // Create a new leaf node
216 // If the new key is a subset, add to to this node
217 search = search[commonPrefix:]
218 if len(search) == 0 {
223 // Create a new edge for the node
235 // Delete is used to delete a key, returning the previous
236 // value and if it was deleted
237 func (t *Tree) Delete(s string) (interface{}, bool) {
243 // Check for key exhaution
244 if len(search) == 0 {
259 // Consume the search prefix
260 if strings.HasPrefix(search, n.prefix) {
261 search = search[len(n.prefix):]
274 // Check if we should delete this node from the parent
275 if parent != nil && len(n.edges) == 0 {
276 parent.delEdge(label)
279 // Check if we should merge this node
280 if n != t.root && len(n.edges) == 1 {
284 // Check if we should merge the parent's other child
285 if parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {
289 return leaf.val, true
292 // DeletePrefix is used to delete the subtree under a prefix
293 // Returns how many nodes were deleted
294 // Use this to delete large subtrees efficiently
295 func (t *Tree) DeletePrefix(s string) int {
296 return t.deletePrefix(nil, t.root, s)
299 // delete does a recursive deletion
300 func (t *Tree) deletePrefix(parent, n *node, prefix string) int {
301 // Check for key exhaustion
302 if len(prefix) == 0 {
303 // Remove the leaf node
305 //recursively walk from all edges of the node to be deleted
306 recursiveWalk(n, func(s string, v interface{}) bool {
313 n.edges = nil // deletes the entire subtree
315 // Check if we should merge the parent's other child
316 if parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {
319 t.size -= subTreeSize
325 child := n.getEdge(label)
326 if child == nil || (!strings.HasPrefix(child.prefix, prefix) && !strings.HasPrefix(prefix, child.prefix)) {
330 // Consume the search prefix
331 if len(child.prefix) > len(prefix) {
332 prefix = prefix[len(prefix):]
334 prefix = prefix[len(child.prefix):]
336 return t.deletePrefix(n, child, prefix)
339 func (n *node) mergeChild() {
342 n.prefix = n.prefix + child.prefix
344 n.edges = child.edges
347 // Get is used to lookup a specific key, returning
348 // the value and if it was found
349 func (t *Tree) Get(s string) (interface{}, bool) {
353 // Check for key exhaution
354 if len(search) == 0 {
356 return n.leaf.val, true
362 n = n.getEdge(search[0])
367 // Consume the search prefix
368 if strings.HasPrefix(search, n.prefix) {
369 search = search[len(n.prefix):]
377 // LongestPrefix is like Get, but instead of an
378 // exact match, it will return the longest prefix match.
379 func (t *Tree) LongestPrefix(s string) (string, interface{}, bool) {
384 // Look for a leaf node
389 // Check for key exhaution
390 if len(search) == 0 {
395 n = n.getEdge(search[0])
400 // Consume the search prefix
401 if strings.HasPrefix(search, n.prefix) {
402 search = search[len(n.prefix):]
408 return last.key, last.val, true
410 return "", nil, false
413 // Minimum is used to return the minimum value in the tree
414 func (t *Tree) Minimum() (string, interface{}, bool) {
418 return n.leaf.key, n.leaf.val, true
420 if len(n.edges) > 0 {
426 return "", nil, false
429 // Maximum is used to return the maximum value in the tree
430 func (t *Tree) Maximum() (string, interface{}, bool) {
433 if num := len(n.edges); num > 0 {
434 n = n.edges[num-1].node
438 return n.leaf.key, n.leaf.val, true
442 return "", nil, false
445 // Walk is used to walk the tree
446 func (t *Tree) Walk(fn WalkFn) {
447 recursiveWalk(t.root, fn)
450 // WalkPrefix is used to walk the tree under a prefix
451 func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
455 // Check for key exhaution
456 if len(search) == 0 {
462 n = n.getEdge(search[0])
467 // Consume the search prefix
468 if strings.HasPrefix(search, n.prefix) {
469 search = search[len(n.prefix):]
471 } else if strings.HasPrefix(n.prefix, search) {
472 // Child may be under our search prefix
482 // WalkPath is used to walk the tree, but only visiting nodes
483 // from the root down to a given leaf. Where WalkPrefix walks
484 // all the entries *under* the given prefix, this walks the
485 // entries *above* the given prefix.
486 func (t *Tree) WalkPath(path string, fn WalkFn) {
490 // Visit the leaf values if any
491 if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
495 // Check for key exhaution
496 if len(search) == 0 {
501 n = n.getEdge(search[0])
506 // Consume the search prefix
507 if strings.HasPrefix(search, n.prefix) {
508 search = search[len(n.prefix):]
515 // recursiveWalk is used to do a pre-order walk of a node
516 // recursively. Returns true if the walk should be aborted
517 func recursiveWalk(n *node, fn WalkFn) bool {
518 // Visit the leaf values if any
519 if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
523 // Recurse on the children
524 for _, e := range n.edges {
525 if recursiveWalk(e.node, fn) {
532 // ToMap is used to walk the tree and convert it into a map
533 func (t *Tree) ToMap() map[string]interface{} {
534 out := make(map[string]interface{}, t.size)
535 t.Walk(func(k string, v interface{}) bool {