radix.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. package radix
  2. import (
  3. "sort"
  4. "strings"
  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(s string, v interface{}) bool
  10. // leafNode is used to represent a value
  11. type leafNode struct {
  12. key string
  13. val interface{}
  14. }
  15. // edge is used to represent an edge node
  16. type edge struct {
  17. label byte
  18. node *node
  19. }
  20. type node struct {
  21. // leaf is used to store possible leaf
  22. leaf *leafNode
  23. // prefix is the common prefix we ignore
  24. prefix string
  25. // Edges should be stored in-order for iteration.
  26. // We avoid a fully materialized slice to save memory,
  27. // since in most cases we expect to be sparse
  28. edges edges
  29. }
  30. func (n *node) isLeaf() bool {
  31. return n.leaf != nil
  32. }
  33. func (n *node) addEdge(e edge) {
  34. n.edges = append(n.edges, e)
  35. n.edges.Sort()
  36. }
  37. func (n *node) replaceEdge(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. if idx < num && n.edges[idx].label == e.label {
  43. n.edges[idx].node = e.node
  44. return
  45. }
  46. panic("replacing missing edge")
  47. }
  48. func (n *node) getEdge(label byte) *node {
  49. num := len(n.edges)
  50. idx := sort.Search(num, func(i int) bool {
  51. return n.edges[i].label >= label
  52. })
  53. if idx < num && n.edges[idx].label == label {
  54. return n.edges[idx].node
  55. }
  56. return nil
  57. }
  58. func (n *node) delEdge(label byte) {
  59. num := len(n.edges)
  60. idx := sort.Search(num, func(i int) bool {
  61. return n.edges[i].label >= label
  62. })
  63. if idx < num && n.edges[idx].label == label {
  64. copy(n.edges[idx:], n.edges[idx+1:])
  65. n.edges[len(n.edges)-1] = edge{}
  66. n.edges = n.edges[:len(n.edges)-1]
  67. }
  68. }
  69. type edges []edge
  70. func (e edges) Len() int {
  71. return len(e)
  72. }
  73. func (e edges) Less(i, j int) bool {
  74. return e[i].label < e[j].label
  75. }
  76. func (e edges) Swap(i, j int) {
  77. e[i], e[j] = e[j], e[i]
  78. }
  79. func (e edges) Sort() {
  80. sort.Sort(e)
  81. }
  82. // Tree implements a radix tree. This can be treated as a
  83. // Dictionary abstract data type. The main advantage over
  84. // a standard hash map is prefix-based lookups and
  85. // ordered iteration,
  86. type Tree struct {
  87. root *node
  88. size int
  89. }
  90. // New returns an empty Tree
  91. func New() *Tree {
  92. return NewFromMap(nil)
  93. }
  94. // NewFromMap returns a new tree containing the keys
  95. // from an existing map
  96. func NewFromMap(m map[string]interface{}) *Tree {
  97. t := &Tree{root: &node{}}
  98. for k, v := range m {
  99. t.Insert(k, v)
  100. }
  101. return t
  102. }
  103. // Len is used to return the number of elements in the tree
  104. func (t *Tree) Len() int {
  105. return t.size
  106. }
  107. // longestPrefix finds the length of the shared prefix
  108. // of two strings
  109. func longestPrefix(k1, k2 string) int {
  110. max := len(k1)
  111. if l := len(k2); l < max {
  112. max = l
  113. }
  114. var i int
  115. for i = 0; i < max; i++ {
  116. if k1[i] != k2[i] {
  117. break
  118. }
  119. }
  120. return i
  121. }
  122. // Insert is used to add a newentry or update
  123. // an existing entry. Returns if updated.
  124. func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
  125. var parent *node
  126. n := t.root
  127. search := s
  128. for {
  129. // Handle key exhaution
  130. if len(search) == 0 {
  131. if n.isLeaf() {
  132. old := n.leaf.val
  133. n.leaf.val = v
  134. return old, true
  135. }
  136. n.leaf = &leafNode{
  137. key: s,
  138. val: v,
  139. }
  140. t.size++
  141. return nil, false
  142. }
  143. // Look for the edge
  144. parent = n
  145. n = n.getEdge(search[0])
  146. // No edge, create one
  147. if n == nil {
  148. e := edge{
  149. label: search[0],
  150. node: &node{
  151. leaf: &leafNode{
  152. key: s,
  153. val: v,
  154. },
  155. prefix: search,
  156. },
  157. }
  158. parent.addEdge(e)
  159. t.size++
  160. return nil, false
  161. }
  162. // Determine longest prefix of the search key on match
  163. commonPrefix := longestPrefix(search, n.prefix)
  164. if commonPrefix == len(n.prefix) {
  165. search = search[commonPrefix:]
  166. continue
  167. }
  168. // Split the node
  169. t.size++
  170. child := &node{
  171. prefix: search[:commonPrefix],
  172. }
  173. parent.replaceEdge(edge{
  174. label: search[0],
  175. node: child,
  176. })
  177. // Restore the existing node
  178. child.addEdge(edge{
  179. label: n.prefix[commonPrefix],
  180. node: n,
  181. })
  182. n.prefix = n.prefix[commonPrefix:]
  183. // Create a new leaf node
  184. leaf := &leafNode{
  185. key: s,
  186. val: v,
  187. }
  188. // If the new key is a subset, add to to this node
  189. search = search[commonPrefix:]
  190. if len(search) == 0 {
  191. child.leaf = leaf
  192. return nil, false
  193. }
  194. // Create a new edge for the node
  195. child.addEdge(edge{
  196. label: search[0],
  197. node: &node{
  198. leaf: leaf,
  199. prefix: search,
  200. },
  201. })
  202. return nil, false
  203. }
  204. }
  205. // Delete is used to delete a key, returning the previous
  206. // value and if it was deleted
  207. func (t *Tree) Delete(s string) (interface{}, bool) {
  208. var parent *node
  209. var label byte
  210. n := t.root
  211. search := s
  212. for {
  213. // Check for key exhaution
  214. if len(search) == 0 {
  215. if !n.isLeaf() {
  216. break
  217. }
  218. goto DELETE
  219. }
  220. // Look for an edge
  221. parent = n
  222. label = search[0]
  223. n = n.getEdge(label)
  224. if n == nil {
  225. break
  226. }
  227. // Consume the search prefix
  228. if strings.HasPrefix(search, n.prefix) {
  229. search = search[len(n.prefix):]
  230. } else {
  231. break
  232. }
  233. }
  234. return nil, false
  235. DELETE:
  236. // Delete the leaf
  237. leaf := n.leaf
  238. n.leaf = nil
  239. t.size--
  240. // Check if we should delete this node from the parent
  241. if parent != nil && len(n.edges) == 0 {
  242. parent.delEdge(label)
  243. }
  244. // Check if we should merge this node
  245. if n != t.root && len(n.edges) == 1 {
  246. n.mergeChild()
  247. }
  248. // Check if we should merge the parent's other child
  249. if parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {
  250. parent.mergeChild()
  251. }
  252. return leaf.val, true
  253. }
  254. func (n *node) mergeChild() {
  255. e := n.edges[0]
  256. child := e.node
  257. n.prefix = n.prefix + child.prefix
  258. n.leaf = child.leaf
  259. n.edges = child.edges
  260. }
  261. // Get is used to lookup a specific key, returning
  262. // the value and if it was found
  263. func (t *Tree) Get(s string) (interface{}, bool) {
  264. n := t.root
  265. search := s
  266. for {
  267. // Check for key exhaution
  268. if len(search) == 0 {
  269. if n.isLeaf() {
  270. return n.leaf.val, true
  271. }
  272. break
  273. }
  274. // Look for an edge
  275. n = n.getEdge(search[0])
  276. if n == nil {
  277. break
  278. }
  279. // Consume the search prefix
  280. if strings.HasPrefix(search, n.prefix) {
  281. search = search[len(n.prefix):]
  282. } else {
  283. break
  284. }
  285. }
  286. return nil, false
  287. }
  288. // LongestPrefix is like Get, but instead of an
  289. // exact match, it will return the longest prefix match.
  290. func (t *Tree) LongestPrefix(s string) (string, interface{}, bool) {
  291. var last *leafNode
  292. n := t.root
  293. search := s
  294. for {
  295. // Look for a leaf node
  296. if n.isLeaf() {
  297. last = n.leaf
  298. }
  299. // Check for key exhaution
  300. if len(search) == 0 {
  301. break
  302. }
  303. // Look for an edge
  304. n = n.getEdge(search[0])
  305. if n == nil {
  306. break
  307. }
  308. // Consume the search prefix
  309. if strings.HasPrefix(search, n.prefix) {
  310. search = search[len(n.prefix):]
  311. } else {
  312. break
  313. }
  314. }
  315. if last != nil {
  316. return last.key, last.val, true
  317. }
  318. return "", nil, false
  319. }
  320. // Minimum is used to return the minimum value in the tree
  321. func (t *Tree) Minimum() (string, interface{}, bool) {
  322. n := t.root
  323. for {
  324. if n.isLeaf() {
  325. return n.leaf.key, n.leaf.val, true
  326. }
  327. if len(n.edges) > 0 {
  328. n = n.edges[0].node
  329. } else {
  330. break
  331. }
  332. }
  333. return "", nil, false
  334. }
  335. // Maximum is used to return the maximum value in the tree
  336. func (t *Tree) Maximum() (string, interface{}, bool) {
  337. n := t.root
  338. for {
  339. if num := len(n.edges); num > 0 {
  340. n = n.edges[num-1].node
  341. continue
  342. }
  343. if n.isLeaf() {
  344. return n.leaf.key, n.leaf.val, true
  345. }
  346. break
  347. }
  348. return "", nil, false
  349. }
  350. // Walk is used to walk the tree
  351. func (t *Tree) Walk(fn WalkFn) {
  352. recursiveWalk(t.root, fn)
  353. }
  354. // WalkPrefix is used to walk the tree under a prefix
  355. func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
  356. n := t.root
  357. search := prefix
  358. for {
  359. // Check for key exhaution
  360. if len(search) == 0 {
  361. recursiveWalk(n, fn)
  362. return
  363. }
  364. // Look for an edge
  365. n = n.getEdge(search[0])
  366. if n == nil {
  367. break
  368. }
  369. // Consume the search prefix
  370. if strings.HasPrefix(search, n.prefix) {
  371. search = search[len(n.prefix):]
  372. } else if strings.HasPrefix(n.prefix, search) {
  373. // Child may be under our search prefix
  374. recursiveWalk(n, fn)
  375. return
  376. } else {
  377. break
  378. }
  379. }
  380. }
  381. // WalkPath is used to walk the tree, but only visiting nodes
  382. // from the root down to a given leaf. Where WalkPrefix walks
  383. // all the entries *under* the given prefix, this walks the
  384. // entries *above* the given prefix.
  385. func (t *Tree) WalkPath(path string, fn WalkFn) {
  386. n := t.root
  387. search := path
  388. for {
  389. // Visit the leaf values if any
  390. if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
  391. return
  392. }
  393. // Check for key exhaution
  394. if len(search) == 0 {
  395. return
  396. }
  397. // Look for an edge
  398. n = n.getEdge(search[0])
  399. if n == nil {
  400. return
  401. }
  402. // Consume the search prefix
  403. if strings.HasPrefix(search, n.prefix) {
  404. search = search[len(n.prefix):]
  405. } else {
  406. break
  407. }
  408. }
  409. }
  410. // recursiveWalk is used to do a pre-order walk of a node
  411. // recursively. Returns true if the walk should be aborted
  412. func recursiveWalk(n *node, fn WalkFn) bool {
  413. // Visit the leaf values if any
  414. if n.leaf != nil && fn(n.leaf.key, n.leaf.val) {
  415. return true
  416. }
  417. // Recurse on the children
  418. for _, e := range n.edges {
  419. if recursiveWalk(e.node, fn) {
  420. return true
  421. }
  422. }
  423. return false
  424. }
  425. // ToMap is used to walk the tree and convert it into a map
  426. func (t *Tree) ToMap() map[string]interface{} {
  427. out := make(map[string]interface{}, t.size)
  428. t.Walk(func(k string, v interface{}) bool {
  429. out[k] = v
  430. return false
  431. })
  432. return out
  433. }