Guest User

Untitled

a guest
Jun 22nd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  1. const toString = require('tree-to-string')
  2. const util = require('util')
  3.  
  4. module.exports = BTree
  5.  
  6. function BTree () {
  7. this.feed = []
  8. }
  9.  
  10. BTree.prototype.put = function (key, value) {
  11. this.insert({key, value})
  12. }
  13.  
  14. BTree.prototype.insert = function (val) {
  15. if (!this.feed.length) {
  16. const node = new Node()
  17. node.values.push(val)
  18. node.seq = 0
  19. this.feed.push(node)
  20. return
  21. }
  22.  
  23. // find leaf
  24. var i
  25. var node = this.feed[this.feed.length - 1]
  26. var next
  27. var tick = this.feed.length
  28.  
  29. const stack = []
  30. const batch = []
  31. const seqs = []
  32.  
  33. while (node.children.length) {
  34. next = node.children[node.children.length - 1]
  35.  
  36. for (i = 0; i < node.values.length; i++) {
  37. const v = node.values[i]
  38. const c = cmp(v, val)
  39.  
  40. if (c === 0) {
  41. var o = node
  42. node = node.clone()
  43. node.values[i] = v
  44. node.seq = tick++
  45. batch.push(node)
  46. this.commit(batch, tick, node, stack, seqs)
  47. return
  48. }
  49. if (c > 0) {
  50. next = node.children[i]
  51. break
  52. }
  53. }
  54.  
  55. stack.push(node)
  56. seqs.push(node.children.indexOf(next))
  57. node = this.feed[next]
  58. }
  59.  
  60. for (i = 0; i < node.values.length; i++) {
  61. const v = node.values[i]
  62. const c = cmp(v, val)
  63.  
  64. if (c === 0) {
  65. node = node.clone()
  66. node.seq = tick++
  67. node.values[i] = val
  68. batch.push(node)
  69. this.commit(batch, tick, node, stack, seqs)
  70. return
  71. }
  72. if (c > 0) break
  73. }
  74.  
  75. node = node.clone()
  76. node.values.splice(i, 0, val)
  77.  
  78. if (node.values.length <= 2) {
  79. node.seq = tick++
  80. batch.push(node)
  81. }
  82.  
  83. while (node.values.length > 2) {
  84. const parent = (stack.pop() || new Node()).clone()
  85. seqs.pop()
  86.  
  87. const left = node.clone()
  88. const right = new Node()
  89.  
  90. right.values.push(left.values.pop())
  91. const mid = left.values.pop()
  92.  
  93. if (left.children.length) {
  94. const b = left.children.pop()
  95. const a = left.children.pop()
  96. right.children.push(a)
  97. right.children.push(b)
  98. }
  99.  
  100. left.seq = tick++
  101. right.seq = tick++
  102. batch.push(left, right)
  103.  
  104. for (i = 0; i < parent.values.length; i++) {
  105. const v = parent.values[i]
  106. if (cmp(v, mid) > 0) break
  107. }
  108.  
  109. parent.values.splice(i, 0, mid)
  110. parent.children.splice(i, 0, 0)
  111. parent.children[i] = left.seq
  112. parent.children[i + 1] = right.seq
  113.  
  114. node = parent
  115. if (node.values.length <= 2) {
  116. node.seq = tick++
  117. batch.push(node)
  118. }
  119. }
  120.  
  121. this.commit(batch, tick, node, stack, seqs)
  122. }
  123.  
  124. BTree.prototype.commit = function (batch, tick, node, stack, seqs) {
  125. while (stack.length) {
  126. const parent = stack.pop().clone()
  127. const seq = seqs.pop()
  128. parent.children[seq] = node.seq
  129. parent.seq = tick++
  130. batch.push(parent)
  131. node = parent
  132. }
  133.  
  134. for (var i= 0 ; i < batch.length; i++) this.feed.push(batch[i])
  135. }
  136.  
  137. BTree.prototype.toString = function () {
  138. var self = this
  139.  
  140. return toString(map(this.feed[this.feed.length - 1]), format)
  141.  
  142. function map (node) {
  143. return {
  144. values: node.values,
  145. children: node.children.map(seq => self.feed[seq]).map(map)
  146. }
  147. }
  148. }
  149.  
  150. function cmp (a, b) {
  151. return a.key < b.key ? -1 : a.key > b.key ? 1 : 0
  152. }
  153.  
  154. function Node () {
  155. this.seq = 0
  156. this.values = []
  157. this.children = []
  158. }
  159.  
  160. Node.prototype.clone = function () {
  161. const node = new Node()
  162. node.seq = this.seq
  163. node.values = this.values.slice(0)
  164. node.children = this.children.slice(0)
  165. return node
  166. }
  167.  
  168. function format (nodes) {
  169. var start = ''
  170. for (var i = 0; i < nodes.length; i++) {
  171. if (i) start += '\n'
  172. start += util.inspect(nodes[i].key) + ' => ' + util.inspect(nodes[i].value)
  173. }
  174. return start
  175. }
Add Comment
Please, Sign In to add comment