node.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. package iradix
  2. import (
  3. "bytes"
  4. "sort"
  5. )
  6. // WalkFn is used when walking the tree. Takes a
  7. // key and value, returning if iteration should
  8. // be terminated.
  9. type WalkFn func(k []byte, v interface{}) bool
  10. // leafNode is used to represent a value
  11. type leafNode struct {
  12. mutateCh chan struct{}
  13. key []byte
  14. val interface{}
  15. }
  16. // edge is used to represent an edge node
  17. type edge struct {
  18. label byte
  19. node *Node
  20. }
  21. // Node is an immutable node in the radix tree
  22. type Node struct {
  23. // mutateCh is closed if this node is modified
  24. mutateCh chan struct{}
  25. // leaf is used to store possible leaf
  26. leaf *leafNode
  27. // prefix is the common prefix we ignore
  28. prefix []byte
  29. // Edges should be stored in-order for iteration.
  30. // We avoid a fully materialized slice to save memory,
  31. // since in most cases we expect to be sparse
  32. edges edges
  33. }
  34. func (n *Node) isLeaf() bool {
  35. return n.leaf != nil
  36. }
  37. func (n *Node) addEdge(e edge) {
  38. num := len(n.edges)
  39. idx := sort.Search(num, func(i int) bool {
  40. return n.edges[i].label >= e.label
  41. })
  42. n.edges = append(n.edges, e)
  43. if idx != num {
  44. copy(n.edges[idx+1:], n.edges[idx:num])
  45. n.edges[idx] = e
  46. }
  47. }
  48. func (n *Node) replaceEdge(e edge) {
  49. num := len(n.edges)
  50. idx := sort.Search(num, func(i int) bool {
  51. return n.edges[i].label >= e.label
  52. })
  53. if idx < num && n.edges[idx].label == e.label {
  54. n.edges[idx].node = e.node
  55. return
  56. }
  57. panic("replacing missing edge")
  58. }
  59. func (n *Node) getEdge(label byte) (int, *Node) {
  60. num := len(n.edges)
  61. idx := sort.Search(num, func(i int) bool {
  62. return n.edges[i].label >= label
  63. })
  64. if idx < num && n.edges[idx].label == label {
  65. return idx, n.edges[idx].node
  66. }
  67. return -1, nil
  68. }
  69. func (n *Node) getLowerBoundEdge(label byte) (int, *Node) {
  70. num := len(n.edges)
  71. idx := sort.Search(num, func(i int) bool {
  72. return n.edges[i].label >= label
  73. })
  74. // we want lower bound behavior so return even if it's not an exact match
  75. if idx < num {
  76. return idx, n.edges[idx].node
  77. }
  78. return -1, nil
  79. }
  80. func (n *Node) delEdge(label byte) {
  81. num := len(n.edges)
  82. idx := sort.Search(num, func(i int) bool {
  83. return n.edges[i].label >= label
  84. })
  85. if idx < num && n.edges[idx].label == label {
  86. copy(n.edges[idx:], n.edges[idx+1:])
  87. n.edges[len(n.edges)-1] = edge{}
  88. n.edges = n.edges[:len(n.edges)-1]
  89. }
  90. }
  91. func (n *Node) GetWatch(k []byte) (<-chan struct{}, interface{}, bool) {
  92. search := k
  93. watch := n.mutateCh
  94. for {
  95. // Check for key exhaustion
  96. if len(search) == 0 {
  97. if n.isLeaf() {
  98. return n.leaf.mutateCh, n.leaf.val, true
  99. }
  100. break
  101. }
  102. // Look for an edge
  103. _, n = n.getEdge(search[0])
  104. if n == nil {
  105. break
  106. }
  107. // Update to the finest granularity as the search makes progress
  108. watch = n.mutateCh
  109. // Consume the search prefix
  110. if bytes.HasPrefix(search, n.prefix) {
  111. search = search[len(n.prefix):]
  112. } else {
  113. break
  114. }
  115. }
  116. return watch, nil, false
  117. }
  118. func (n *Node) Get(k []byte) (interface{}, bool) {
  119. _, val, ok := n.GetWatch(k)
  120. return val, ok
  121. }
  122. // LongestPrefix is like Get, but instead of an
  123. // exact match, it will return the longest prefix match.
  124. func (n *Node) LongestPrefix(k []byte) ([]byte, interface{}, bool) {
  125. var last *leafNode
  126. search := k
  127. for {
  128. // Look for a leaf node
  129. if n.isLeaf() {
  130. last = n.leaf
  131. }
  132. // Check for key exhaution
  133. if len(search) == 0 {
  134. break
  135. }
  136. // Look for an edge
  137. _, n = n.getEdge(search[0])
  138. if n == nil {
  139. break
  140. }
  141. // Consume the search prefix
  142. if bytes.HasPrefix(search, n.prefix) {
  143. search = search[len(n.prefix):]
  144. } else {
  145. break
  146. }
  147. }
  148. if last != nil {
  149. return last.key, last.val, true
  150. }
  151. return nil, nil, false
  152. }
  153. // Minimum is used to return the minimum value in the tree
  154. func (n *Node) Minimum() ([]byte, interface{}, bool) {
  155. for {
  156. if n.isLeaf() {
  157. return n.leaf.key, n.leaf.val, true
  158. }
  159. if len(n.edges) > 0 {
  160. n = n.edges[0].node
  161. } else {
  162. break
  163. }
  164. }
  165. return nil, nil, false
  166. }
  167. // Maximum is used to return the maximum value in the tree
  168. func (n *Node) Maximum() ([]byte, interface{}, bool) {
  169. for {
  170. if num := len(n.edges); num > 0 {
  171. n = n.edges[num-1].node
  172. continue
  173. }
  174. if n.isLeaf() {
  175. return n.leaf.key, n.leaf.val, true
  176. } else {
  177. break
  178. }
  179. }
  180. return nil, nil, false
  181. }
  182. // Iterator is used to return an iterator at
  183. // the given node to walk the tree
  184. func (n *Node) Iterator() *Iterator {
  185. return &Iterator{node: n}
  186. }
  187. // ReverseIterator is used to return an iterator at
  188. // the given node to walk the tree backwards
  189. func (n *Node) ReverseIterator() *ReverseIterator {
  190. return NewReverseIterator(n)
  191. }
  192. // rawIterator is used to return a raw iterator at the given node to walk the
  193. // tree.
  194. func (n *Node) rawIterator() *rawIterator {
  195. iter := &rawIterator{node: n}
  196. iter.Next()
  197. return iter
  198. }
  199. // Walk is used to walk the tree
  200. func (n *Node) Walk(fn WalkFn) {
  201. recursiveWalk(n, fn)
  202. }
  203. // WalkBackwards is used to walk the tree in reverse order
  204. func (n *Node) WalkBackwards(fn WalkFn) {
  205. reverseRecursiveWalk(n, fn)
  206. }
  207. // WalkPrefix is used to walk the tree under a prefix
  208. func (n *Node) WalkPrefix(prefix []byte, fn WalkFn) {
  209. search := prefix
  210. for {
  211. // Check for key exhaution
  212. if len(search) == 0 {
  213. recursiveWalk(n, fn)
  214. return
  215. }
  216. // Look for an edge
  217. _, n = n.getEdge(search[0])
  218. if n == nil {
  219. break
  220. }
  221. // Consume the search prefix
  222. if bytes.HasPrefix(search, n.prefix) {
  223. search = search[len(n.prefix):]
  224. } else if bytes.HasPrefix(n.prefix, search) {
  225. // Child may be under our search prefix
  226. recursiveWalk(n, fn)
  227. return
  228. } else {
  229. break
  230. }
  231. }
  232. }
  233. // WalkPath is used to walk the tree, but only visiting nodes
  234. // from the root down to a given leaf. Where WalkPrefix walks
  235. // all the entries *under* the given prefix, this walks the
  236. // entries *above* the given prefix.
  237. func (n *Node) WalkPath(path []byte, fn WalkFn) {
  238. search := path
  239. for {
  240. // Visit the leaf values if any
  241. if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
  242. return
  243. }
  244. // Check for key exhaution
  245. if len(search) == 0 {
  246. return
  247. }
  248. // Look for an edge
  249. _, n = n.getEdge(search[0])
  250. if n == nil {
  251. return
  252. }
  253. // Consume the search prefix
  254. if bytes.HasPrefix(search, n.prefix) {
  255. search = search[len(n.prefix):]
  256. } else {
  257. break
  258. }
  259. }
  260. }
  261. // recursiveWalk is used to do a pre-order walk of a node
  262. // recursively. Returns true if the walk should be aborted
  263. func recursiveWalk(n *Node, fn WalkFn) bool {
  264. // Visit the leaf values if any
  265. if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
  266. return true
  267. }
  268. // Recurse on the children
  269. for _, e := range n.edges {
  270. if recursiveWalk(e.node, fn) {
  271. return true
  272. }
  273. }
  274. return false
  275. }
  276. // reverseRecursiveWalk is used to do a reverse pre-order
  277. // walk of a node recursively. Returns true if the walk
  278. // should be aborted
  279. func reverseRecursiveWalk(n *Node, fn WalkFn) bool {
  280. // Visit the leaf values if any
  281. if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
  282. return true
  283. }
  284. // Recurse on the children in reverse order
  285. for i := len(n.edges) - 1; i >= 0; i-- {
  286. e := n.edges[i]
  287. if reverseRecursiveWalk(e.node, fn) {
  288. return true
  289. }
  290. }
  291. return false
  292. }