You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

btree.go 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. // Copyright 2020 Joshua J Baker. All rights reserved.
  2. // Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. package btree
  5. import (
  6. "sync"
  7. )
  8. const maxItems = 255 // max items per node. max children is +1
  9. const minItems = maxItems * 40 / 100
  10. type cow struct {
  11. _ int // it cannot be an empty struct
  12. }
  13. type node struct {
  14. cow *cow
  15. leaf bool
  16. numItems int16
  17. count int
  18. items [maxItems]interface{}
  19. children *[maxItems + 1]*node
  20. }
  21. // BTree is an ordered set items
  22. type BTree struct {
  23. mu *sync.RWMutex
  24. cow *cow
  25. root *node
  26. count int
  27. less func(a, b interface{}) bool
  28. locks bool
  29. }
  30. func (tr *BTree) newNode(leaf bool) *node {
  31. n := &node{leaf: leaf}
  32. if !leaf {
  33. n.children = new([maxItems + 1]*node)
  34. }
  35. n.cow = tr.cow
  36. return n
  37. }
  38. // PathHint is a utility type used with the *Hint() functions. Hints provide
  39. // faster operations for clustered keys.
  40. type PathHint struct {
  41. used [8]bool
  42. path [8]uint8
  43. }
  44. // New returns a new BTree
  45. func New(less func(a, b interface{}) bool) *BTree {
  46. return newBTree(less, true)
  47. }
  48. // NewNonConcurrent returns a new BTree which is not safe for concurrent
  49. // write operations by multiple goroutines.
  50. //
  51. // This is useful for when you do not need the BTree to manage the locking,
  52. // but would rather do it yourself.
  53. func NewNonConcurrent(less func(a, b interface{}) bool) *BTree {
  54. return newBTree(less, false)
  55. }
  56. func newBTree(less func(a, b interface{}) bool, locks bool) *BTree {
  57. if less == nil {
  58. panic("nil less")
  59. }
  60. tr := new(BTree)
  61. tr.mu = new(sync.RWMutex)
  62. tr.less = less
  63. tr.locks = locks
  64. return tr
  65. }
  66. // Less is a convenience function that performs a comparison of two items
  67. // using the same "less" function provided to New.
  68. func (tr *BTree) Less(a, b interface{}) bool {
  69. return tr.less(a, b)
  70. }
  71. func (n *node) find(key interface{}, less func(a, b interface{}) bool,
  72. hint *PathHint, depth int,
  73. ) (index int16, found bool) {
  74. low := int16(0)
  75. high := n.numItems - 1
  76. if hint != nil && depth < 8 && hint.used[depth] {
  77. index = int16(hint.path[depth])
  78. if index >= n.numItems {
  79. // tail item
  80. if less(n.items[n.numItems-1], key) {
  81. if less(key, n.items[n.numItems-1]) {
  82. index = n.numItems - 1
  83. found = true
  84. goto path_match
  85. } else {
  86. index = n.numItems
  87. goto path_match
  88. }
  89. }
  90. index = n.numItems - 1
  91. }
  92. if less(key, n.items[index]) {
  93. if index == 0 || less(n.items[index-1], key) {
  94. goto path_match
  95. }
  96. high = index - 1
  97. } else if less(n.items[index], key) {
  98. low = index + 1
  99. } else {
  100. found = true
  101. goto path_match
  102. }
  103. }
  104. for low <= high {
  105. mid := low + ((high+1)-low)/2
  106. if !less(key, n.items[mid]) {
  107. low = mid + 1
  108. } else {
  109. high = mid - 1
  110. }
  111. }
  112. if low > 0 && !less(n.items[low-1], key) {
  113. index = low - 1
  114. found = true
  115. } else {
  116. index = low
  117. found = false
  118. }
  119. if hint == nil || depth >= 8 {
  120. return index, found
  121. }
  122. path_match:
  123. hint.used[depth] = true
  124. if n.leaf && found {
  125. hint.path[depth] = byte(index + 1)
  126. } else {
  127. hint.path[depth] = byte(index)
  128. }
  129. return index, found
  130. }
  131. // SetHint sets or replace a value for a key using a path hint
  132. func (tr *BTree) SetHint(item interface{}, hint *PathHint) (prev interface{}) {
  133. if item == nil {
  134. panic("nil item")
  135. }
  136. if tr.lock() {
  137. defer tr.unlock()
  138. }
  139. return tr.setHint(item, hint)
  140. }
  141. func (tr *BTree) setHint(item interface{}, hint *PathHint) (prev interface{}) {
  142. if tr.root == nil {
  143. tr.root = tr.newNode(true)
  144. tr.root.items[0] = item
  145. tr.root.numItems = 1
  146. tr.root.count = 1
  147. tr.count = 1
  148. return
  149. }
  150. prev = tr.nodeSet(&tr.root, item, tr.less, hint, 0)
  151. if prev != nil {
  152. return prev
  153. }
  154. if tr.root.numItems == maxItems {
  155. n := tr.cowLoad(&tr.root)
  156. right, median := tr.nodeSplit(n)
  157. tr.root = tr.newNode(false)
  158. tr.root.children[0] = n
  159. tr.root.items[0] = median
  160. tr.root.children[1] = right
  161. tr.root.numItems = 1
  162. tr.root.count = n.count + 1 + right.count
  163. }
  164. tr.count++
  165. return prev
  166. }
  167. // Set or replace a value for a key
  168. func (tr *BTree) Set(item interface{}) (prev interface{}) {
  169. return tr.SetHint(item, nil)
  170. }
  171. func (tr *BTree) nodeSplit(n *node) (right *node, median interface{}) {
  172. right = tr.newNode(n.leaf)
  173. median = n.items[maxItems/2]
  174. copy(right.items[:maxItems/2], n.items[maxItems/2+1:])
  175. if !n.leaf {
  176. copy(right.children[:maxItems/2+1], n.children[maxItems/2+1:])
  177. }
  178. right.numItems = maxItems / 2
  179. if !n.leaf {
  180. for i := maxItems/2 + 1; i < maxItems+1; i++ {
  181. n.children[i] = nil
  182. }
  183. }
  184. for i := maxItems / 2; i < maxItems; i++ {
  185. n.items[i] = nil
  186. }
  187. n.numItems = maxItems / 2
  188. // update counts
  189. n.updateCount()
  190. right.updateCount()
  191. return right, median
  192. }
  193. func (n *node) updateCount() {
  194. n.count = int(n.numItems)
  195. if !n.leaf {
  196. for i := 0; i <= int(n.numItems); i++ {
  197. n.count += n.children[i].count
  198. }
  199. }
  200. }
  201. // This operation should not be inlined because it's expensive and rarely
  202. // called outside of heavy copy-on-write situations. Marking it "noinline"
  203. // allows for the parent cowLoad to be inlined.
  204. // go:noinline
  205. func (tr *BTree) copy(n *node) *node {
  206. n2 := *n
  207. n2.cow = tr.cow
  208. copy(n2.items[:], n.items[:])
  209. if n.children != nil {
  210. n2.children = new([maxItems + 1]*node)
  211. copy(n2.children[:], n.children[:])
  212. }
  213. return &n2
  214. }
  215. // cowLoad loads the provide node and, if needed, performs a copy-on-write.
  216. func (tr *BTree) cowLoad(cn **node) *node {
  217. if (*cn).cow != tr.cow {
  218. *cn = tr.copy(*cn)
  219. }
  220. return *cn
  221. }
  222. func (tr *BTree) nodeSet(cn **node, item interface{},
  223. less func(a, b interface{}) bool, hint *PathHint, depth int,
  224. ) (prev interface{}) {
  225. n := tr.cowLoad(cn)
  226. i, found := n.find(item, less, hint, depth)
  227. if found {
  228. prev = n.items[i]
  229. n.items[i] = item
  230. return prev
  231. }
  232. if n.leaf {
  233. copy(n.items[i+1:n.numItems+1], n.items[i:n.numItems])
  234. n.items[i] = item
  235. n.numItems++
  236. n.count++
  237. return nil
  238. }
  239. prev = tr.nodeSet(&n.children[i], item, less, hint, depth+1)
  240. if prev != nil {
  241. return prev
  242. }
  243. if n.children[i].numItems == maxItems {
  244. right, median := tr.nodeSplit(n.children[i])
  245. copy(n.children[i+1:], n.children[i:])
  246. copy(n.items[i+1:], n.items[i:])
  247. n.items[i] = median
  248. n.children[i+1] = right
  249. n.numItems++
  250. }
  251. n.count++
  252. return nil
  253. }
  254. func (n *node) scan(iter func(item interface{}) bool) bool {
  255. if n.leaf {
  256. for i := int16(0); i < n.numItems; i++ {
  257. if !iter(n.items[i]) {
  258. return false
  259. }
  260. }
  261. return true
  262. }
  263. for i := int16(0); i < n.numItems; i++ {
  264. if !n.children[i].scan(iter) {
  265. return false
  266. }
  267. if !iter(n.items[i]) {
  268. return false
  269. }
  270. }
  271. return n.children[n.numItems].scan(iter)
  272. }
  273. // Get a value for key
  274. func (tr *BTree) Get(key interface{}) interface{} {
  275. return tr.GetHint(key, nil)
  276. }
  277. // GetHint gets a value for key using a path hint
  278. func (tr *BTree) GetHint(key interface{}, hint *PathHint) interface{} {
  279. if tr.rlock() {
  280. defer tr.runlock()
  281. }
  282. if tr.root == nil || key == nil {
  283. return nil
  284. }
  285. depth := 0
  286. n := tr.root
  287. for {
  288. i, found := n.find(key, tr.less, hint, depth)
  289. if found {
  290. return n.items[i]
  291. }
  292. if n.leaf {
  293. return nil
  294. }
  295. n = n.children[i]
  296. depth++
  297. }
  298. }
  299. // Len returns the number of items in the tree
  300. func (tr *BTree) Len() int {
  301. return tr.count
  302. }
  303. // Delete a value for a key
  304. func (tr *BTree) Delete(key interface{}) interface{} {
  305. return tr.DeleteHint(key, nil)
  306. }
  307. // DeleteHint deletes a value for a key using a path hint
  308. func (tr *BTree) DeleteHint(key interface{}, hint *PathHint) interface{} {
  309. if tr.lock() {
  310. defer tr.unlock()
  311. }
  312. return tr.deleteHint(key, hint)
  313. }
  314. func (tr *BTree) deleteHint(key interface{}, hint *PathHint) interface{} {
  315. if tr.root == nil || key == nil {
  316. return nil
  317. }
  318. prev := tr.delete(&tr.root, false, key, tr.less, hint, 0)
  319. if prev == nil {
  320. return nil
  321. }
  322. if tr.root.numItems == 0 && !tr.root.leaf {
  323. tr.root = tr.root.children[0]
  324. }
  325. tr.count--
  326. if tr.count == 0 {
  327. tr.root = nil
  328. }
  329. return prev
  330. }
  331. func (tr *BTree) delete(cn **node, max bool, key interface{},
  332. less func(a, b interface{}) bool, hint *PathHint, depth int,
  333. ) interface{} {
  334. n := tr.cowLoad(cn)
  335. var i int16
  336. var found bool
  337. if max {
  338. i, found = n.numItems-1, true
  339. } else {
  340. i, found = n.find(key, less, hint, depth)
  341. }
  342. if n.leaf {
  343. if found {
  344. prev := n.items[i]
  345. // found the items at the leaf, remove it and return.
  346. copy(n.items[i:], n.items[i+1:n.numItems])
  347. n.items[n.numItems-1] = nil
  348. n.numItems--
  349. n.count--
  350. return prev
  351. }
  352. return nil
  353. }
  354. var prev interface{}
  355. if found {
  356. if max {
  357. i++
  358. prev = tr.delete(&n.children[i], true, "", less, nil, 0)
  359. } else {
  360. prev = n.items[i]
  361. maxItem := tr.delete(&n.children[i], true, "", less, nil, 0)
  362. n.items[i] = maxItem
  363. }
  364. } else {
  365. prev = tr.delete(&n.children[i], max, key, less, hint, depth+1)
  366. }
  367. if prev == nil {
  368. return nil
  369. }
  370. n.count--
  371. if n.children[i].numItems >= minItems {
  372. return prev
  373. }
  374. // merge / rebalance nodes
  375. if i == n.numItems {
  376. i--
  377. }
  378. n.children[i] = tr.cowLoad(&n.children[i])
  379. n.children[i+1] = tr.cowLoad(&n.children[i+1])
  380. if n.children[i].numItems+n.children[i+1].numItems+1 < maxItems {
  381. // merge left + item + right
  382. n.children[i].items[n.children[i].numItems] = n.items[i]
  383. copy(n.children[i].items[n.children[i].numItems+1:],
  384. n.children[i+1].items[:n.children[i+1].numItems])
  385. if !n.children[0].leaf {
  386. copy(n.children[i].children[n.children[i].numItems+1:],
  387. n.children[i+1].children[:n.children[i+1].numItems+1])
  388. }
  389. n.children[i].numItems += n.children[i+1].numItems + 1
  390. n.children[i].count += n.children[i+1].count + 1
  391. copy(n.items[i:], n.items[i+1:n.numItems])
  392. copy(n.children[i+1:], n.children[i+2:n.numItems+1])
  393. n.items[n.numItems-1] = nil
  394. n.children[n.numItems] = nil
  395. n.numItems--
  396. } else if n.children[i].numItems > n.children[i+1].numItems {
  397. // move left -> right
  398. copy(n.children[i+1].items[1:],
  399. n.children[i+1].items[:n.children[i+1].numItems])
  400. if !n.children[0].leaf {
  401. copy(n.children[i+1].children[1:],
  402. n.children[i+1].children[:n.children[i+1].numItems+1])
  403. }
  404. n.children[i+1].items[0] = n.items[i]
  405. if !n.children[0].leaf {
  406. n.children[i+1].children[0] =
  407. n.children[i].children[n.children[i].numItems]
  408. n.children[i+1].count += n.children[i+1].children[0].count
  409. }
  410. n.children[i+1].numItems++
  411. n.children[i+1].count++
  412. n.items[i] = n.children[i].items[n.children[i].numItems-1]
  413. n.children[i].items[n.children[i].numItems-1] = nil
  414. if !n.children[0].leaf {
  415. n.children[i].children[n.children[i].numItems] = nil
  416. n.children[i].count -= n.children[i+1].children[0].count
  417. }
  418. n.children[i].numItems--
  419. n.children[i].count--
  420. } else {
  421. // move left <- right
  422. n.children[i].items[n.children[i].numItems] = n.items[i]
  423. if !n.children[0].leaf {
  424. n.children[i].children[n.children[i].numItems+1] =
  425. n.children[i+1].children[0]
  426. n.children[i].count +=
  427. n.children[i].children[n.children[i].numItems+1].count
  428. }
  429. n.children[i].numItems++
  430. n.children[i].count++
  431. n.items[i] = n.children[i+1].items[0]
  432. copy(n.children[i+1].items[:],
  433. n.children[i+1].items[1:n.children[i+1].numItems])
  434. n.children[i+1].items[n.children[i+1].numItems-1] = nil
  435. if !n.children[0].leaf {
  436. copy(n.children[i+1].children[:],
  437. n.children[i+1].children[1:n.children[i+1].numItems+1])
  438. n.children[i+1].children[n.children[i+1].numItems] = nil
  439. n.children[i+1].count -=
  440. n.children[i].children[n.children[i].numItems].count
  441. }
  442. n.children[i+1].numItems--
  443. n.children[i+1].count--
  444. }
  445. return prev
  446. }
  447. // Ascend the tree within the range [pivot, last]
  448. // Pass nil for pivot to scan all item in ascending order
  449. // Return false to stop iterating
  450. func (tr *BTree) Ascend(pivot interface{}, iter func(item interface{}) bool) {
  451. if tr.rlock() {
  452. defer tr.runlock()
  453. }
  454. if tr.root == nil {
  455. return
  456. }
  457. if pivot == nil {
  458. tr.root.scan(iter)
  459. } else if tr.root != nil {
  460. tr.root.ascend(pivot, tr.less, nil, 0, iter)
  461. }
  462. }
  463. func (n *node) ascend(pivot interface{}, less func(a, b interface{}) bool,
  464. hint *PathHint, depth int, iter func(item interface{}) bool,
  465. ) bool {
  466. i, found := n.find(pivot, less, hint, depth)
  467. if !found {
  468. if !n.leaf {
  469. if !n.children[i].ascend(pivot, less, hint, depth+1, iter) {
  470. return false
  471. }
  472. }
  473. }
  474. for ; i < n.numItems; i++ {
  475. if !iter(n.items[i]) {
  476. return false
  477. }
  478. if !n.leaf {
  479. if !n.children[i+1].scan(iter) {
  480. return false
  481. }
  482. }
  483. }
  484. return true
  485. }
  486. func (n *node) reverse(iter func(item interface{}) bool) bool {
  487. if n.leaf {
  488. for i := n.numItems - 1; i >= 0; i-- {
  489. if !iter(n.items[i]) {
  490. return false
  491. }
  492. }
  493. return true
  494. }
  495. if !n.children[n.numItems].reverse(iter) {
  496. return false
  497. }
  498. for i := n.numItems - 1; i >= 0; i-- {
  499. if !iter(n.items[i]) {
  500. return false
  501. }
  502. if !n.children[i].reverse(iter) {
  503. return false
  504. }
  505. }
  506. return true
  507. }
  508. // Descend the tree within the range [pivot, first]
  509. // Pass nil for pivot to scan all item in descending order
  510. // Return false to stop iterating
  511. func (tr *BTree) Descend(pivot interface{}, iter func(item interface{}) bool) {
  512. if tr.rlock() {
  513. defer tr.runlock()
  514. }
  515. if tr.root == nil {
  516. return
  517. }
  518. if pivot == nil {
  519. tr.root.reverse(iter)
  520. } else if tr.root != nil {
  521. tr.root.descend(pivot, tr.less, nil, 0, iter)
  522. }
  523. }
  524. func (n *node) descend(pivot interface{}, less func(a, b interface{}) bool,
  525. hint *PathHint, depth int, iter func(item interface{}) bool,
  526. ) bool {
  527. i, found := n.find(pivot, less, hint, depth)
  528. if !found {
  529. if !n.leaf {
  530. if !n.children[i].descend(pivot, less, hint, depth+1, iter) {
  531. return false
  532. }
  533. }
  534. i--
  535. }
  536. for ; i >= 0; i-- {
  537. if !iter(n.items[i]) {
  538. return false
  539. }
  540. if !n.leaf {
  541. if !n.children[i].reverse(iter) {
  542. return false
  543. }
  544. }
  545. }
  546. return true
  547. }
  548. // Load is for bulk loading pre-sorted items
  549. func (tr *BTree) Load(item interface{}) interface{} {
  550. if item == nil {
  551. panic("nil item")
  552. }
  553. if tr.lock() {
  554. defer tr.unlock()
  555. }
  556. if tr.root == nil {
  557. return tr.setHint(item, nil)
  558. }
  559. n := tr.cowLoad(&tr.root)
  560. for {
  561. n.count++ // optimistically update counts
  562. if n.leaf {
  563. if n.numItems < maxItems-2 {
  564. if tr.less(n.items[n.numItems-1], item) {
  565. n.items[n.numItems] = item
  566. n.numItems++
  567. tr.count++
  568. return nil
  569. }
  570. }
  571. break
  572. }
  573. n = tr.cowLoad(&n.children[n.numItems])
  574. }
  575. // revert the counts
  576. n = tr.root
  577. for {
  578. n.count--
  579. if n.leaf {
  580. break
  581. }
  582. n = n.children[n.numItems]
  583. }
  584. return tr.setHint(item, nil)
  585. }
  586. // Min returns the minimum item in tree.
  587. // Returns nil if the tree has no items.
  588. func (tr *BTree) Min() interface{} {
  589. if tr.rlock() {
  590. defer tr.runlock()
  591. }
  592. if tr.root == nil {
  593. return nil
  594. }
  595. n := tr.root
  596. for {
  597. if n.leaf {
  598. return n.items[0]
  599. }
  600. n = n.children[0]
  601. }
  602. }
  603. // Max returns the maximum item in tree.
  604. // Returns nil if the tree has no items.
  605. func (tr *BTree) Max() interface{} {
  606. if tr.rlock() {
  607. defer tr.runlock()
  608. }
  609. if tr.root == nil {
  610. return nil
  611. }
  612. n := tr.root
  613. for {
  614. if n.leaf {
  615. return n.items[n.numItems-1]
  616. }
  617. n = n.children[n.numItems]
  618. }
  619. }
  620. // PopMin removes the minimum item in tree and returns it.
  621. // Returns nil if the tree has no items.
  622. func (tr *BTree) PopMin() interface{} {
  623. if tr.lock() {
  624. defer tr.unlock()
  625. }
  626. if tr.root == nil {
  627. return nil
  628. }
  629. n := tr.cowLoad(&tr.root)
  630. var item interface{}
  631. for {
  632. n.count-- // optimistically update counts
  633. if n.leaf {
  634. item = n.items[0]
  635. if n.numItems == minItems {
  636. break
  637. }
  638. copy(n.items[:], n.items[1:])
  639. n.items[n.numItems-1] = nil
  640. n.numItems--
  641. tr.count--
  642. if tr.count == 0 {
  643. tr.root = nil
  644. }
  645. return item
  646. }
  647. n = tr.cowLoad(&n.children[0])
  648. }
  649. // revert the counts
  650. n = tr.root
  651. for {
  652. n.count++
  653. if n.leaf {
  654. break
  655. }
  656. n = n.children[0]
  657. }
  658. return tr.deleteHint(item, nil)
  659. }
  660. // PopMax removes the minimum item in tree and returns it.
  661. // Returns nil if the tree has no items.
  662. func (tr *BTree) PopMax() interface{} {
  663. if tr.lock() {
  664. defer tr.unlock()
  665. }
  666. if tr.root == nil {
  667. return nil
  668. }
  669. n := tr.cowLoad(&tr.root)
  670. var item interface{}
  671. for {
  672. n.count-- // optimistically update counts
  673. if n.leaf {
  674. item = n.items[n.numItems-1]
  675. if n.numItems == minItems {
  676. break
  677. }
  678. n.items[n.numItems-1] = nil
  679. n.numItems--
  680. tr.count--
  681. if tr.count == 0 {
  682. tr.root = nil
  683. }
  684. return item
  685. }
  686. n = tr.cowLoad(&n.children[n.numItems])
  687. }
  688. // revert the counts
  689. n = tr.root
  690. for {
  691. n.count++
  692. if n.leaf {
  693. break
  694. }
  695. n = n.children[n.numItems]
  696. }
  697. return tr.deleteHint(item, nil)
  698. }
  699. // GetAt returns the value at index.
  700. // Return nil if the tree is empty or the index is out of bounds.
  701. func (tr *BTree) GetAt(index int) interface{} {
  702. if tr.rlock() {
  703. defer tr.runlock()
  704. }
  705. if tr.root == nil || index < 0 || index >= tr.count {
  706. return nil
  707. }
  708. n := tr.root
  709. for {
  710. if n.leaf {
  711. return n.items[index]
  712. }
  713. i := 0
  714. for ; i < int(n.numItems); i++ {
  715. if index < n.children[i].count {
  716. break
  717. } else if index == n.children[i].count {
  718. return n.items[i]
  719. }
  720. index -= n.children[i].count + 1
  721. }
  722. n = n.children[i]
  723. }
  724. }
  725. // DeleteAt deletes the item at index.
  726. // Return nil if the tree is empty or the index is out of bounds.
  727. func (tr *BTree) DeleteAt(index int) interface{} {
  728. if tr.lock() {
  729. defer tr.unlock()
  730. }
  731. if tr.root == nil || index < 0 || index >= tr.count {
  732. return nil
  733. }
  734. var pathbuf [8]uint8 // track the path
  735. path := pathbuf[:0]
  736. var item interface{}
  737. n := tr.cowLoad(&tr.root)
  738. outer:
  739. for {
  740. n.count-- // optimistically update counts
  741. if n.leaf {
  742. // the index is the item position
  743. item = n.items[index]
  744. if n.numItems == minItems {
  745. path = append(path, uint8(index))
  746. break outer
  747. }
  748. copy(n.items[index:], n.items[index+1:n.numItems])
  749. n.items[n.numItems-1] = nil
  750. n.numItems--
  751. tr.count--
  752. if tr.count == 0 {
  753. tr.root = nil
  754. }
  755. return item
  756. }
  757. i := 0
  758. for ; i < int(n.numItems); i++ {
  759. if index < n.children[i].count {
  760. break
  761. } else if index == n.children[i].count {
  762. item = n.items[i]
  763. path = append(path, uint8(i))
  764. break outer
  765. }
  766. index -= n.children[i].count + 1
  767. }
  768. path = append(path, uint8(i))
  769. n = tr.cowLoad(&n.children[i])
  770. }
  771. // revert the counts
  772. var hint PathHint
  773. n = tr.root
  774. for i := 0; i < len(path); i++ {
  775. if i < len(hint.path) {
  776. hint.path[i] = path[i]
  777. hint.used[i] = true
  778. }
  779. n.count++
  780. if !n.leaf {
  781. n = n.children[uint8(path[i])]
  782. }
  783. }
  784. return tr.deleteHint(item, &hint)
  785. }
  786. // Height returns the height of the tree.
  787. // Returns zero if tree has no items.
  788. func (tr *BTree) Height() int {
  789. if tr.rlock() {
  790. defer tr.runlock()
  791. }
  792. var height int
  793. if tr.root != nil {
  794. n := tr.root
  795. for {
  796. height++
  797. if n.leaf {
  798. break
  799. }
  800. n = n.children[n.numItems]
  801. }
  802. }
  803. return height
  804. }
  805. // Walk iterates over all items in tree, in order.
  806. // The items param will contain one or more items.
  807. func (tr *BTree) Walk(iter func(item []interface{})) {
  808. if tr.rlock() {
  809. defer tr.runlock()
  810. }
  811. if tr.root != nil {
  812. tr.root.walk(iter)
  813. }
  814. }
  815. func (n *node) walk(iter func(item []interface{})) {
  816. if n.leaf {
  817. iter(n.items[:n.numItems])
  818. } else {
  819. for i := int16(0); i < n.numItems; i++ {
  820. n.children[i].walk(iter)
  821. iter(n.items[i : i+1])
  822. }
  823. n.children[n.numItems].walk(iter)
  824. }
  825. }
  826. // Copy the tree. This operation is very fast because it only performs a
  827. // shadowed copy.
  828. func (tr *BTree) Copy() *BTree {
  829. if tr.lock() {
  830. defer tr.unlock()
  831. }
  832. tr.cow = new(cow)
  833. tr2 := *tr
  834. tr2.mu = new(sync.RWMutex)
  835. tr2.cow = new(cow)
  836. return &tr2
  837. }
  838. func (tr *BTree) lock() bool {
  839. if tr.locks {
  840. tr.mu.Lock()
  841. }
  842. return tr.locks
  843. }
  844. func (tr *BTree) unlock() {
  845. tr.mu.Unlock()
  846. }
  847. func (tr *BTree) rlock() bool {
  848. if tr.locks {
  849. tr.mu.RLock()
  850. }
  851. return tr.locks
  852. }
  853. func (tr *BTree) runlock() {
  854. tr.mu.RUnlock()
  855. }