blob: 04814c1323fb9f377fbb84441534ace2e2701b71 [file] [log] [blame]
divyadesai81bb7ba2020-03-11 11:45:23 +00001package iradix
2
3// rawIterator visits each of the nodes in the tree, even the ones that are not
4// leaves. It keeps track of the effective path (what a leaf at a given node
5// would be called), which is useful for comparing trees.
6type rawIterator struct {
7 // node is the starting node in the tree for the iterator.
8 node *Node
9
10 // stack keeps track of edges in the frontier.
11 stack []rawStackEntry
12
13 // pos is the current position of the iterator.
14 pos *Node
15
16 // path is the effective path of the current iterator position,
17 // regardless of whether the current node is a leaf.
18 path string
19}
20
21// rawStackEntry is used to keep track of the cumulative common path as well as
22// its associated edges in the frontier.
23type rawStackEntry struct {
24 path string
25 edges edges
26}
27
28// Front returns the current node that has been iterated to.
29func (i *rawIterator) Front() *Node {
30 return i.pos
31}
32
33// Path returns the effective path of the current node, even if it's not actually
34// a leaf.
35func (i *rawIterator) Path() string {
36 return i.path
37}
38
39// Next advances the iterator to the next node.
40func (i *rawIterator) Next() {
41 // Initialize our stack if needed.
42 if i.stack == nil && i.node != nil {
43 i.stack = []rawStackEntry{
44 rawStackEntry{
45 edges: edges{
46 edge{node: i.node},
47 },
48 },
49 }
50 }
51
52 for len(i.stack) > 0 {
53 // Inspect the last element of the stack.
54 n := len(i.stack)
55 last := i.stack[n-1]
56 elem := last.edges[0].node
57
58 // Update the stack.
59 if len(last.edges) > 1 {
60 i.stack[n-1].edges = last.edges[1:]
61 } else {
62 i.stack = i.stack[:n-1]
63 }
64
65 // Push the edges onto the frontier.
66 if len(elem.edges) > 0 {
67 path := last.path + string(elem.prefix)
68 i.stack = append(i.stack, rawStackEntry{path, elem.edges})
69 }
70
71 i.pos = elem
72 i.path = last.path + string(elem.prefix)
73 return
74 }
75
76 i.pos = nil
77 i.path = ""
78}