raw_iter.go 1.8 KB

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