radix.go 8.5 KB

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