iradix.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package iradix
  2. import (
  3. "bytes"
  4. "github.com/hashicorp/golang-lru/simplelru"
  5. )
  6. const (
  7. // defaultModifiedCache is the default size of the modified node
  8. // cache used per transaction. This is used to cache the updates
  9. // to the nodes near the root, while the leaves do not need to be
  10. // cached. This is important for very large transactions to prevent
  11. // the modified cache from growing to be enormous.
  12. defaultModifiedCache = 8192
  13. )
  14. // Tree implements an immutable radix tree. This can be treated as a
  15. // Dictionary abstract data type. The main advantage over a standard
  16. // hash map is prefix-based lookups and ordered iteration. The immutability
  17. // means that it is safe to concurrently read from a Tree without any
  18. // coordination.
  19. type Tree struct {
  20. root *Node
  21. size int
  22. }
  23. // New returns an empty Tree
  24. func New() *Tree {
  25. t := &Tree{root: &Node{}}
  26. return t
  27. }
  28. // Len is used to return the number of elements in the tree
  29. func (t *Tree) Len() int {
  30. return t.size
  31. }
  32. // Txn is a transaction on the tree. This transaction is applied
  33. // atomically and returns a new tree when committed. A transaction
  34. // is not thread safe, and should only be used by a single goroutine.
  35. type Txn struct {
  36. root *Node
  37. size int
  38. modified *simplelru.LRU
  39. }
  40. // Txn starts a new transaction that can be used to mutate the tree
  41. func (t *Tree) Txn() *Txn {
  42. txn := &Txn{
  43. root: t.root,
  44. size: t.size,
  45. }
  46. return txn
  47. }
  48. // writeNode returns a node to be modified, if the current
  49. // node as already been modified during the course of
  50. // the transaction, it is used in-place.
  51. func (t *Txn) writeNode(n *Node) *Node {
  52. // Ensure the modified set exists
  53. if t.modified == nil {
  54. lru, err := simplelru.NewLRU(defaultModifiedCache, nil)
  55. if err != nil {
  56. panic(err)
  57. }
  58. t.modified = lru
  59. }
  60. // If this node has already been modified, we can
  61. // continue to use it during this transaction.
  62. if _, ok := t.modified.Get(n); ok {
  63. return n
  64. }
  65. // Copy the existing node
  66. nc := new(Node)
  67. if n.prefix != nil {
  68. nc.prefix = make([]byte, len(n.prefix))
  69. copy(nc.prefix, n.prefix)
  70. }
  71. if n.leaf != nil {
  72. nc.leaf = new(leafNode)
  73. *nc.leaf = *n.leaf
  74. }
  75. if len(n.edges) != 0 {
  76. nc.edges = make([]edge, len(n.edges))
  77. copy(nc.edges, n.edges)
  78. }
  79. // Mark this node as modified
  80. t.modified.Add(n, nil)
  81. return nc
  82. }
  83. // insert does a recursive insertion
  84. func (t *Txn) insert(n *Node, k, search []byte, v interface{}) (*Node, interface{}, bool) {
  85. // Handle key exhaution
  86. if len(search) == 0 {
  87. nc := t.writeNode(n)
  88. if n.isLeaf() {
  89. old := nc.leaf.val
  90. nc.leaf.val = v
  91. return nc, old, true
  92. } else {
  93. nc.leaf = &leafNode{
  94. key: k,
  95. val: v,
  96. }
  97. return nc, nil, false
  98. }
  99. }
  100. // Look for the edge
  101. idx, child := n.getEdge(search[0])
  102. // No edge, create one
  103. if child == nil {
  104. e := edge{
  105. label: search[0],
  106. node: &Node{
  107. leaf: &leafNode{
  108. key: k,
  109. val: v,
  110. },
  111. prefix: search,
  112. },
  113. }
  114. nc := t.writeNode(n)
  115. nc.addEdge(e)
  116. return nc, nil, false
  117. }
  118. // Determine longest prefix of the search key on match
  119. commonPrefix := longestPrefix(search, child.prefix)
  120. if commonPrefix == len(child.prefix) {
  121. search = search[commonPrefix:]
  122. newChild, oldVal, didUpdate := t.insert(child, k, search, v)
  123. if newChild != nil {
  124. nc := t.writeNode(n)
  125. nc.edges[idx].node = newChild
  126. return nc, oldVal, didUpdate
  127. }
  128. return nil, oldVal, didUpdate
  129. }
  130. // Split the node
  131. nc := t.writeNode(n)
  132. splitNode := &Node{
  133. prefix: search[:commonPrefix],
  134. }
  135. nc.replaceEdge(edge{
  136. label: search[0],
  137. node: splitNode,
  138. })
  139. // Restore the existing child node
  140. modChild := t.writeNode(child)
  141. splitNode.addEdge(edge{
  142. label: modChild.prefix[commonPrefix],
  143. node: modChild,
  144. })
  145. modChild.prefix = modChild.prefix[commonPrefix:]
  146. // Create a new leaf node
  147. leaf := &leafNode{
  148. key: k,
  149. val: v,
  150. }
  151. // If the new key is a subset, add to to this node
  152. search = search[commonPrefix:]
  153. if len(search) == 0 {
  154. splitNode.leaf = leaf
  155. return nc, nil, false
  156. }
  157. // Create a new edge for the node
  158. splitNode.addEdge(edge{
  159. label: search[0],
  160. node: &Node{
  161. leaf: leaf,
  162. prefix: search,
  163. },
  164. })
  165. return nc, nil, false
  166. }
  167. // delete does a recursive deletion
  168. func (t *Txn) delete(parent, n *Node, search []byte) (*Node, *leafNode) {
  169. // Check for key exhaution
  170. if len(search) == 0 {
  171. if !n.isLeaf() {
  172. return nil, nil
  173. }
  174. // Remove the leaf node
  175. nc := t.writeNode(n)
  176. nc.leaf = nil
  177. // Check if this node should be merged
  178. if n != t.root && len(nc.edges) == 1 {
  179. nc.mergeChild()
  180. }
  181. return nc, n.leaf
  182. }
  183. // Look for an edge
  184. label := search[0]
  185. idx, child := n.getEdge(label)
  186. if child == nil || !bytes.HasPrefix(search, child.prefix) {
  187. return nil, nil
  188. }
  189. // Consume the search prefix
  190. search = search[len(child.prefix):]
  191. newChild, leaf := t.delete(n, child, search)
  192. if newChild == nil {
  193. return nil, nil
  194. }
  195. // Copy this node
  196. nc := t.writeNode(n)
  197. // Delete the edge if the node has no edges
  198. if newChild.leaf == nil && len(newChild.edges) == 0 {
  199. nc.delEdge(label)
  200. if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() {
  201. nc.mergeChild()
  202. }
  203. } else {
  204. nc.edges[idx].node = newChild
  205. }
  206. return nc, leaf
  207. }
  208. // Insert is used to add or update a given key. The return provides
  209. // the previous value and a bool indicating if any was set.
  210. func (t *Txn) Insert(k []byte, v interface{}) (interface{}, bool) {
  211. newRoot, oldVal, didUpdate := t.insert(t.root, k, k, v)
  212. if newRoot != nil {
  213. t.root = newRoot
  214. }
  215. if !didUpdate {
  216. t.size++
  217. }
  218. return oldVal, didUpdate
  219. }
  220. // Delete is used to delete a given key. Returns the old value if any,
  221. // and a bool indicating if the key was set.
  222. func (t *Txn) Delete(k []byte) (interface{}, bool) {
  223. newRoot, leaf := t.delete(nil, t.root, k)
  224. if newRoot != nil {
  225. t.root = newRoot
  226. }
  227. if leaf != nil {
  228. t.size--
  229. return leaf.val, true
  230. }
  231. return nil, false
  232. }
  233. // Root returns the current root of the radix tree within this
  234. // transaction. The root is not safe across insert and delete operations,
  235. // but can be used to read the current state during a transaction.
  236. func (t *Txn) Root() *Node {
  237. return t.root
  238. }
  239. // Get is used to lookup a specific key, returning
  240. // the value and if it was found
  241. func (t *Txn) Get(k []byte) (interface{}, bool) {
  242. return t.root.Get(k)
  243. }
  244. // Commit is used to finalize the transaction and return a new tree
  245. func (t *Txn) Commit() *Tree {
  246. t.modified = nil
  247. return &Tree{t.root, t.size}
  248. }
  249. // Insert is used to add or update a given key. The return provides
  250. // the new tree, previous value and a bool indicating if any was set.
  251. func (t *Tree) Insert(k []byte, v interface{}) (*Tree, interface{}, bool) {
  252. txn := t.Txn()
  253. old, ok := txn.Insert(k, v)
  254. return txn.Commit(), old, ok
  255. }
  256. // Delete is used to delete a given key. Returns the new tree,
  257. // old value if any, and a bool indicating if the key was set.
  258. func (t *Tree) Delete(k []byte) (*Tree, interface{}, bool) {
  259. txn := t.Txn()
  260. old, ok := txn.Delete(k)
  261. return txn.Commit(), old, ok
  262. }
  263. // Root returns the root node of the tree which can be used for richer
  264. // query operations.
  265. func (t *Tree) Root() *Node {
  266. return t.root
  267. }
  268. // Get is used to lookup a specific key, returning
  269. // the value and if it was found
  270. func (t *Tree) Get(k []byte) (interface{}, bool) {
  271. return t.root.Get(k)
  272. }
  273. // longestPrefix finds the length of the shared prefix
  274. // of two strings
  275. func longestPrefix(k1, k2 []byte) int {
  276. max := len(k1)
  277. if l := len(k2); l < max {
  278. max = l
  279. }
  280. var i int
  281. for i = 0; i < max; i++ {
  282. if k1[i] != k2[i] {
  283. break
  284. }
  285. }
  286. return i
  287. }
  288. // concat two byte slices, returning a third new copy
  289. func concat(a, b []byte) []byte {
  290. c := make([]byte, len(a)+len(b))
  291. copy(c, a)
  292. copy(c[len(a):], b)
  293. return c
  294. }