node64.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. package numtree
  2. import (
  3. "fmt"
  4. "math/bits"
  5. )
  6. // Key64BitSize is an alias for bitsize of 64-bit radix tree's key.
  7. const Key64BitSize = 64
  8. var (
  9. masks64 = []uint64{
  10. 0x0000000000000000, 0x8000000000000000, 0xc000000000000000, 0xe000000000000000,
  11. 0xf000000000000000, 0xf800000000000000, 0xfc00000000000000, 0xfe00000000000000,
  12. 0xff00000000000000, 0xff80000000000000, 0xffc0000000000000, 0xffe0000000000000,
  13. 0xfff0000000000000, 0xfff8000000000000, 0xfffc000000000000, 0xfffe000000000000,
  14. 0xffff000000000000, 0xffff800000000000, 0xffffc00000000000, 0xffffe00000000000,
  15. 0xfffff00000000000, 0xfffff80000000000, 0xfffffc0000000000, 0xfffffe0000000000,
  16. 0xffffff0000000000, 0xffffff8000000000, 0xffffffc000000000, 0xffffffe000000000,
  17. 0xfffffff000000000, 0xfffffff800000000, 0xfffffffc00000000, 0xfffffffe00000000,
  18. 0xffffffff00000000, 0xffffffff80000000, 0xffffffffc0000000, 0xffffffffe0000000,
  19. 0xfffffffff0000000, 0xfffffffff8000000, 0xfffffffffc000000, 0xfffffffffe000000,
  20. 0xffffffffff000000, 0xffffffffff800000, 0xffffffffffc00000, 0xffffffffffe00000,
  21. 0xfffffffffff00000, 0xfffffffffff80000, 0xfffffffffffc0000, 0xfffffffffffe0000,
  22. 0xffffffffffff0000, 0xffffffffffff8000, 0xffffffffffffc000, 0xffffffffffffe000,
  23. 0xfffffffffffff000, 0xfffffffffffff800, 0xfffffffffffffc00, 0xfffffffffffffe00,
  24. 0xffffffffffffff00, 0xffffffffffffff80, 0xffffffffffffffc0, 0xffffffffffffffe0,
  25. 0xfffffffffffffff0, 0xfffffffffffffff8, 0xfffffffffffffffc, 0xfffffffffffffffe,
  26. 0xffffffffffffffff}
  27. )
  28. // Node64 is an element of radix tree with 64-bit unsigned integer as a key.
  29. type Node64 struct {
  30. // Key stores key for current node.
  31. Key uint64
  32. // Bits is a number of significant bits in Key.
  33. Bits uint8
  34. // Leaf indicates if the node is leaf node and contains any data in Value.
  35. Leaf bool
  36. // Value contains data associated with key.
  37. Value interface{}
  38. chld [2]*Node64
  39. }
  40. // Dot dumps tree to Graphviz .dot format
  41. func (n *Node64) Dot() string {
  42. body := ""
  43. i := 0
  44. queue := []*Node64{n}
  45. for len(queue) > 0 {
  46. c := queue[0]
  47. body += fmt.Sprintf("N%d %s\n", i, c.dotString())
  48. if c != nil && (c.chld[0] != nil || c.chld[1] != nil) {
  49. body += fmt.Sprintf("N%d -> { N%d N%d }\n", i, i+len(queue), i+len(queue)+1)
  50. queue = append(append(queue, c.chld[0]), c.chld[1])
  51. }
  52. queue = queue[1:]
  53. i++
  54. }
  55. return "digraph d {\n" + body + "}\n"
  56. }
  57. // Insert puts new leaf to radix tree and returns pointer to new root. The method uses copy on write strategy so old root doesn't see the change.
  58. func (n *Node64) Insert(key uint64, bits int, value interface{}) *Node64 {
  59. if bits < 0 {
  60. bits = 0
  61. } else if bits > Key64BitSize {
  62. bits = Key64BitSize
  63. }
  64. return n.insert(newNode64(key, uint8(bits), true, value))
  65. }
  66. // InplaceInsert puts new leaf to radix tree (or replaces value in existing one). The method inserts data directly to current tree so make sure you have exclusive access to it.
  67. func (n *Node64) InplaceInsert(key uint64, bits int, value interface{}) *Node64 {
  68. // Adjust bits.
  69. if bits < 0 {
  70. bits = 0
  71. } else if bits > Key64BitSize {
  72. bits = Key64BitSize
  73. }
  74. return n.inplaceInsert(key, uint8(bits), value)
  75. }
  76. // Enumerate returns channel which is populated by nodes in order of their keys.
  77. func (n *Node64) Enumerate() chan *Node64 {
  78. ch := make(chan *Node64)
  79. go func() {
  80. defer close(ch)
  81. if n == nil {
  82. return
  83. }
  84. n.enumerate(ch)
  85. }()
  86. return ch
  87. }
  88. // Match locates node which key is equal to or "contains" the key passed as argument.
  89. func (n *Node64) Match(key uint64, bits int) (interface{}, bool) {
  90. if n == nil {
  91. return n, false
  92. }
  93. if bits < 0 {
  94. bits = 0
  95. } else if bits > Key64BitSize {
  96. bits = Key64BitSize
  97. }
  98. r := n.match(key, uint8(bits))
  99. if r == nil {
  100. return nil, false
  101. }
  102. return r.Value, true
  103. }
  104. // ExactMatch locates node which exactly matches given key.
  105. func (n *Node64) ExactMatch(key uint64, bits int) (interface{}, bool) {
  106. if n == nil {
  107. return n, false
  108. }
  109. if bits < 0 {
  110. bits = 0
  111. } else if bits > Key64BitSize {
  112. bits = Key64BitSize
  113. }
  114. r := n.exactMatch(key, uint8(bits))
  115. if r == nil {
  116. return nil, false
  117. }
  118. return r.Value, true
  119. }
  120. // Delete removes subtree which is contained by given key. The method uses copy on write strategy.
  121. func (n *Node64) Delete(key uint64, bits int) (*Node64, bool) {
  122. if n == nil {
  123. return n, false
  124. }
  125. if bits < 0 {
  126. bits = 0
  127. } else if bits > Key64BitSize {
  128. bits = Key64BitSize
  129. }
  130. return n.del(key, uint8(bits))
  131. }
  132. func (n *Node64) dotString() string {
  133. if n == nil {
  134. return "[label=\"nil\"]"
  135. }
  136. if n.Leaf {
  137. v := fmt.Sprintf("%q", fmt.Sprintf("%#v", n.Value))
  138. return fmt.Sprintf("[label=\"k: %016x, b: %d, v: \\\"%s\\\"\"]", n.Key, n.Bits, v[1:len(v)-1])
  139. }
  140. return fmt.Sprintf("[label=\"k: %016x, b: %d\"]", n.Key, n.Bits)
  141. }
  142. func (n *Node64) insert(c *Node64) *Node64 {
  143. if n == nil {
  144. return c
  145. }
  146. bits := uint8(bits.LeadingZeros64((n.Key ^ c.Key) | ^masks64[n.Bits] | ^masks64[c.Bits]))
  147. if bits < n.Bits {
  148. branch := (n.Key >> (Key64BitSize - 1 - bits)) & 1
  149. if bits == c.Bits {
  150. c.chld[branch] = n
  151. return c
  152. }
  153. m := newNode64(c.Key&masks64[bits], bits, false, nil)
  154. m.chld[branch] = n
  155. m.chld[1-branch] = c
  156. return m
  157. }
  158. if c.Bits == n.Bits {
  159. c.chld = n.chld
  160. return c
  161. }
  162. m := newNode64(n.Key, n.Bits, n.Leaf, n.Value)
  163. m.chld = n.chld
  164. branch := (c.Key >> (Key64BitSize - 1 - bits)) & 1
  165. m.chld[branch] = m.chld[branch].insert(c)
  166. return m
  167. }
  168. func (n *Node64) inplaceInsert(key uint64, sbits uint8, value interface{}) *Node64 {
  169. var (
  170. p *Node64
  171. branch uint64
  172. )
  173. r := n
  174. for n != nil {
  175. cbits := uint8(bits.LeadingZeros64((n.Key ^ key) | ^masks64[n.Bits] | ^masks64[sbits]))
  176. if cbits < n.Bits {
  177. pBranch := branch
  178. branch = (n.Key >> (Key64BitSize - 1 - cbits)) & 1
  179. var m *Node64
  180. if cbits == sbits {
  181. m = newNode64(key, sbits, true, value)
  182. m.chld[branch] = n
  183. } else {
  184. m = newNode64(key&masks64[cbits], cbits, false, nil)
  185. m.chld[1-branch] = newNode64(key, sbits, true, value)
  186. }
  187. m.chld[branch] = n
  188. if p == nil {
  189. r = m
  190. } else {
  191. p.chld[pBranch] = m
  192. }
  193. return r
  194. }
  195. if sbits == n.Bits {
  196. n.Key = key
  197. n.Leaf = true
  198. n.Value = value
  199. return r
  200. }
  201. p = n
  202. branch = (key >> (Key64BitSize - 1 - cbits)) & 1
  203. n = n.chld[branch]
  204. }
  205. n = newNode64(key, sbits, true, value)
  206. if p == nil {
  207. return n
  208. }
  209. p.chld[branch] = n
  210. return r
  211. }
  212. func (n *Node64) enumerate(ch chan *Node64) {
  213. if n.Leaf {
  214. ch <- n
  215. }
  216. if n.chld[0] != nil {
  217. n.chld[0].enumerate(ch)
  218. }
  219. if n.chld[1] != nil {
  220. n.chld[1].enumerate(ch)
  221. }
  222. }
  223. func (n *Node64) match(key uint64, bits uint8) *Node64 {
  224. if n.Bits > bits {
  225. return nil
  226. }
  227. if n.Bits == bits {
  228. if n.Leaf && (n.Key^key)&masks64[n.Bits] == 0 {
  229. return n
  230. }
  231. return nil
  232. }
  233. if (n.Key^key)&masks64[n.Bits] != 0 {
  234. return nil
  235. }
  236. c := n.chld[(key>>(Key64BitSize-1-n.Bits))&1]
  237. if c != nil {
  238. r := c.match(key, bits)
  239. if r != nil {
  240. return r
  241. }
  242. }
  243. if n.Leaf {
  244. return n
  245. }
  246. return nil
  247. }
  248. func (n *Node64) exactMatch(key uint64, bits uint8) *Node64 {
  249. if n.Bits > bits {
  250. return nil
  251. }
  252. if n.Bits == bits {
  253. if n.Leaf && (n.Key^key)&masks64[n.Bits] == 0 {
  254. return n
  255. }
  256. return nil
  257. }
  258. if (n.Key^key)&masks64[n.Bits] != 0 {
  259. return nil
  260. }
  261. c := n.chld[(key>>(Key64BitSize-1-n.Bits))&1]
  262. if c != nil {
  263. r := c.exactMatch(key, bits)
  264. if r != nil {
  265. return r
  266. }
  267. }
  268. return nil
  269. }
  270. func (n *Node64) del(key uint64, bits uint8) (*Node64, bool) {
  271. if bits <= n.Bits {
  272. if (n.Key^key)&masks64[bits] == 0 {
  273. return nil, true
  274. }
  275. return n, false
  276. }
  277. if (n.Key^key)&masks64[n.Bits] != 0 {
  278. return n, false
  279. }
  280. branch := (key >> (Key64BitSize - 1 - n.Bits)) & 1
  281. c := n.chld[branch]
  282. if c == nil {
  283. return n, false
  284. }
  285. c, ok := c.del(key, bits)
  286. if !ok {
  287. return n, false
  288. }
  289. if c == nil && !n.Leaf {
  290. return n.chld[1-branch], true
  291. }
  292. m := newNode64(n.Key, n.Bits, n.Leaf, n.Value)
  293. m.chld = n.chld
  294. m.chld[branch] = c
  295. return m, true
  296. }
  297. func newNode64(key uint64, bits uint8, leaf bool, value interface{}) *Node64 {
  298. return &Node64{
  299. Key: key,
  300. Bits: bits,
  301. Leaf: leaf,
  302. Value: value}
  303. }