iter.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package iradix
  2. import (
  3. "bytes"
  4. )
  5. // Iterator is used to iterate over a set of nodes
  6. // in pre-order
  7. type Iterator struct {
  8. node *Node
  9. stack []edges
  10. }
  11. // SeekPrefixWatch is used to seek the iterator to a given prefix
  12. // and returns the watch channel of the finest granularity
  13. func (i *Iterator) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) {
  14. // Wipe the stack
  15. i.stack = nil
  16. n := i.node
  17. watch = n.mutateCh
  18. search := prefix
  19. for {
  20. // Check for key exhaustion
  21. if len(search) == 0 {
  22. i.node = n
  23. return
  24. }
  25. // Look for an edge
  26. _, n = n.getEdge(search[0])
  27. if n == nil {
  28. i.node = nil
  29. return
  30. }
  31. // Update to the finest granularity as the search makes progress
  32. watch = n.mutateCh
  33. // Consume the search prefix
  34. if bytes.HasPrefix(search, n.prefix) {
  35. search = search[len(n.prefix):]
  36. } else if bytes.HasPrefix(n.prefix, search) {
  37. i.node = n
  38. return
  39. } else {
  40. i.node = nil
  41. return
  42. }
  43. }
  44. }
  45. // SeekPrefix is used to seek the iterator to a given prefix
  46. func (i *Iterator) SeekPrefix(prefix []byte) {
  47. i.SeekPrefixWatch(prefix)
  48. }
  49. func (i *Iterator) recurseMin(n *Node) *Node {
  50. // Traverse to the minimum child
  51. if n.leaf != nil {
  52. return n
  53. }
  54. nEdges := len(n.edges)
  55. if nEdges > 1 {
  56. // Add all the other edges to the stack (the min node will be added as
  57. // we recurse)
  58. i.stack = append(i.stack, n.edges[1:])
  59. }
  60. if nEdges > 0 {
  61. return i.recurseMin(n.edges[0].node)
  62. }
  63. // Shouldn't be possible
  64. return nil
  65. }
  66. // SeekLowerBound is used to seek the iterator to the smallest key that is
  67. // greater or equal to the given key. There is no watch variant as it's hard to
  68. // predict based on the radix structure which node(s) changes might affect the
  69. // result.
  70. func (i *Iterator) SeekLowerBound(key []byte) {
  71. // Wipe the stack. Unlike Prefix iteration, we need to build the stack as we
  72. // go because we need only a subset of edges of many nodes in the path to the
  73. // leaf with the lower bound. Note that the iterator will still recurse into
  74. // children that we don't traverse on the way to the reverse lower bound as it
  75. // walks the stack.
  76. i.stack = []edges{}
  77. // i.node starts off in the common case as pointing to the root node of the
  78. // tree. By the time we return we have either found a lower bound and setup
  79. // the stack to traverse all larger keys, or we have not and the stack and
  80. // node should both be nil to prevent the iterator from assuming it is just
  81. // iterating the whole tree from the root node. Either way this needs to end
  82. // up as nil so just set it here.
  83. n := i.node
  84. i.node = nil
  85. search := key
  86. found := func(n *Node) {
  87. i.stack = append(i.stack, edges{edge{node: n}})
  88. }
  89. findMin := func(n *Node) {
  90. n = i.recurseMin(n)
  91. if n != nil {
  92. found(n)
  93. return
  94. }
  95. }
  96. for {
  97. // Compare current prefix with the search key's same-length prefix.
  98. var prefixCmp int
  99. if len(n.prefix) < len(search) {
  100. prefixCmp = bytes.Compare(n.prefix, search[0:len(n.prefix)])
  101. } else {
  102. prefixCmp = bytes.Compare(n.prefix, search)
  103. }
  104. if prefixCmp > 0 {
  105. // Prefix is larger, that means the lower bound is greater than the search
  106. // and from now on we need to follow the minimum path to the smallest
  107. // leaf under this subtree.
  108. findMin(n)
  109. return
  110. }
  111. if prefixCmp < 0 {
  112. // Prefix is smaller than search prefix, that means there is no lower
  113. // bound
  114. i.node = nil
  115. return
  116. }
  117. // Prefix is equal, we are still heading for an exact match. If this is a
  118. // leaf and an exact match we're done.
  119. if n.leaf != nil && bytes.Equal(n.leaf.key, key) {
  120. found(n)
  121. return
  122. }
  123. // Consume the search prefix if the current node has one. Note that this is
  124. // safe because if n.prefix is longer than the search slice prefixCmp would
  125. // have been > 0 above and the method would have already returned.
  126. search = search[len(n.prefix):]
  127. if len(search) == 0 {
  128. // We've exhausted the search key, but the current node is not an exact
  129. // match or not a leaf. That means that the leaf value if it exists, and
  130. // all child nodes must be strictly greater, the smallest key in this
  131. // subtree must be the lower bound.
  132. findMin(n)
  133. return
  134. }
  135. // Otherwise, take the lower bound next edge.
  136. idx, lbNode := n.getLowerBoundEdge(search[0])
  137. if lbNode == nil {
  138. return
  139. }
  140. // Create stack edges for the all strictly higher edges in this node.
  141. if idx+1 < len(n.edges) {
  142. i.stack = append(i.stack, n.edges[idx+1:])
  143. }
  144. // Recurse
  145. n = lbNode
  146. }
  147. }
  148. // Next returns the next node in order
  149. func (i *Iterator) Next() ([]byte, interface{}, bool) {
  150. // Initialize our stack if needed
  151. if i.stack == nil && i.node != nil {
  152. i.stack = []edges{
  153. {
  154. edge{node: i.node},
  155. },
  156. }
  157. }
  158. for len(i.stack) > 0 {
  159. // Inspect the last element of the stack
  160. n := len(i.stack)
  161. last := i.stack[n-1]
  162. elem := last[0].node
  163. // Update the stack
  164. if len(last) > 1 {
  165. i.stack[n-1] = last[1:]
  166. } else {
  167. i.stack = i.stack[:n-1]
  168. }
  169. // Push the edges onto the frontier
  170. if len(elem.edges) > 0 {
  171. i.stack = append(i.stack, elem.edges)
  172. }
  173. // Return the leaf values if any
  174. if elem.leaf != nil {
  175. return elem.leaf.key, elem.leaf.val, true
  176. }
  177. }
  178. return nil, nil, false
  179. }