Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

786 linhas
17 KiB

  1. // Copyright 2014 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package btree
  15. import (
  16. "flag"
  17. "fmt"
  18. "math/rand"
  19. "reflect"
  20. "sort"
  21. "sync"
  22. "testing"
  23. "time"
  24. )
  25. func init() {
  26. seed := time.Now().Unix()
  27. fmt.Println(seed)
  28. rand.Seed(seed)
  29. }
  30. // perm returns a random permutation of n Int items in the range [0, n).
  31. func perm(n int) (out []Item) {
  32. for _, v := range rand.Perm(n) {
  33. out = append(out, Int(v))
  34. }
  35. return
  36. }
  37. // rang returns an ordered list of Int items in the range [0, n).
  38. func rang(n int) (out []Item) {
  39. for i := 0; i < n; i++ {
  40. out = append(out, Int(i))
  41. }
  42. return
  43. }
  44. // all extracts all items from a tree in order as a slice.
  45. func all(t *BTree) (out []Item) {
  46. t.Ascend(func(a Item) bool {
  47. out = append(out, a)
  48. return true
  49. })
  50. return
  51. }
  52. // rangerev returns a reversed ordered list of Int items in the range [0, n).
  53. func rangrev(n int) (out []Item) {
  54. for i := n - 1; i >= 0; i-- {
  55. out = append(out, Int(i))
  56. }
  57. return
  58. }
  59. // allrev extracts all items from a tree in reverse order as a slice.
  60. func allrev(t *BTree) (out []Item) {
  61. t.Descend(func(a Item) bool {
  62. out = append(out, a)
  63. return true
  64. })
  65. return
  66. }
  67. var btreeDegree = flag.Int("degree", 32, "B-Tree degree")
  68. func TestBTree(t *testing.T) {
  69. tr := New(*btreeDegree)
  70. const treeSize = 10000
  71. for i := 0; i < 10; i++ {
  72. if min := tr.Min(); min != nil {
  73. t.Fatalf("empty min, got %+v", min)
  74. }
  75. if max := tr.Max(); max != nil {
  76. t.Fatalf("empty max, got %+v", max)
  77. }
  78. for _, item := range perm(treeSize) {
  79. if x := tr.ReplaceOrInsert(item); x != nil {
  80. t.Fatal("insert found item", item)
  81. }
  82. }
  83. for _, item := range perm(treeSize) {
  84. if x := tr.ReplaceOrInsert(item); x == nil {
  85. t.Fatal("insert didn't find item", item)
  86. }
  87. }
  88. if min, want := tr.Min(), Item(Int(0)); min != want {
  89. t.Fatalf("min: want %+v, got %+v", want, min)
  90. }
  91. if max, want := tr.Max(), Item(Int(treeSize-1)); max != want {
  92. t.Fatalf("max: want %+v, got %+v", want, max)
  93. }
  94. got := all(tr)
  95. want := rang(treeSize)
  96. if !reflect.DeepEqual(got, want) {
  97. t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want)
  98. }
  99. gotrev := allrev(tr)
  100. wantrev := rangrev(treeSize)
  101. if !reflect.DeepEqual(gotrev, wantrev) {
  102. t.Fatalf("mismatch:\n got: %v\nwant: %v", got, want)
  103. }
  104. for _, item := range perm(treeSize) {
  105. if x := tr.Delete(item); x == nil {
  106. t.Fatalf("didn't find %v", item)
  107. }
  108. }
  109. if got = all(tr); len(got) > 0 {
  110. t.Fatalf("some left!: %v", got)
  111. }
  112. }
  113. }
  114. func ExampleBTree() {
  115. tr := New(*btreeDegree)
  116. for i := Int(0); i < 10; i++ {
  117. tr.ReplaceOrInsert(i)
  118. }
  119. fmt.Println("len: ", tr.Len())
  120. fmt.Println("get3: ", tr.Get(Int(3)))
  121. fmt.Println("get100: ", tr.Get(Int(100)))
  122. fmt.Println("del4: ", tr.Delete(Int(4)))
  123. fmt.Println("del100: ", tr.Delete(Int(100)))
  124. fmt.Println("replace5: ", tr.ReplaceOrInsert(Int(5)))
  125. fmt.Println("replace100:", tr.ReplaceOrInsert(Int(100)))
  126. fmt.Println("min: ", tr.Min())
  127. fmt.Println("delmin: ", tr.DeleteMin())
  128. fmt.Println("max: ", tr.Max())
  129. fmt.Println("delmax: ", tr.DeleteMax())
  130. fmt.Println("len: ", tr.Len())
  131. // Output:
  132. // len: 10
  133. // get3: 3
  134. // get100: <nil>
  135. // del4: 4
  136. // del100: <nil>
  137. // replace5: 5
  138. // replace100: <nil>
  139. // min: 0
  140. // delmin: 0
  141. // max: 100
  142. // delmax: 100
  143. // len: 8
  144. }
  145. func TestDeleteMin(t *testing.T) {
  146. tr := New(3)
  147. for _, v := range perm(100) {
  148. tr.ReplaceOrInsert(v)
  149. }
  150. var got []Item
  151. for v := tr.DeleteMin(); v != nil; v = tr.DeleteMin() {
  152. got = append(got, v)
  153. }
  154. if want := rang(100); !reflect.DeepEqual(got, want) {
  155. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  156. }
  157. }
  158. func TestDeleteMax(t *testing.T) {
  159. tr := New(3)
  160. for _, v := range perm(100) {
  161. tr.ReplaceOrInsert(v)
  162. }
  163. var got []Item
  164. for v := tr.DeleteMax(); v != nil; v = tr.DeleteMax() {
  165. got = append(got, v)
  166. }
  167. // Reverse our list.
  168. for i := 0; i < len(got)/2; i++ {
  169. got[i], got[len(got)-i-1] = got[len(got)-i-1], got[i]
  170. }
  171. if want := rang(100); !reflect.DeepEqual(got, want) {
  172. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  173. }
  174. }
  175. func TestAscendRange(t *testing.T) {
  176. tr := New(2)
  177. for _, v := range perm(100) {
  178. tr.ReplaceOrInsert(v)
  179. }
  180. var got []Item
  181. tr.AscendRange(Int(40), Int(60), func(a Item) bool {
  182. got = append(got, a)
  183. return true
  184. })
  185. if want := rang(100)[40:60]; !reflect.DeepEqual(got, want) {
  186. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  187. }
  188. got = got[:0]
  189. tr.AscendRange(Int(40), Int(60), func(a Item) bool {
  190. if a.(Int) > 50 {
  191. return false
  192. }
  193. got = append(got, a)
  194. return true
  195. })
  196. if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) {
  197. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  198. }
  199. }
  200. func TestDescendRange(t *testing.T) {
  201. tr := New(2)
  202. for _, v := range perm(100) {
  203. tr.ReplaceOrInsert(v)
  204. }
  205. var got []Item
  206. tr.DescendRange(Int(60), Int(40), func(a Item) bool {
  207. got = append(got, a)
  208. return true
  209. })
  210. if want := rangrev(100)[39:59]; !reflect.DeepEqual(got, want) {
  211. t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want)
  212. }
  213. got = got[:0]
  214. tr.DescendRange(Int(60), Int(40), func(a Item) bool {
  215. if a.(Int) < 50 {
  216. return false
  217. }
  218. got = append(got, a)
  219. return true
  220. })
  221. if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) {
  222. t.Fatalf("descendrange:\n got: %v\nwant: %v", got, want)
  223. }
  224. }
  225. func TestAscendLessThan(t *testing.T) {
  226. tr := New(*btreeDegree)
  227. for _, v := range perm(100) {
  228. tr.ReplaceOrInsert(v)
  229. }
  230. var got []Item
  231. tr.AscendLessThan(Int(60), func(a Item) bool {
  232. got = append(got, a)
  233. return true
  234. })
  235. if want := rang(100)[:60]; !reflect.DeepEqual(got, want) {
  236. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  237. }
  238. got = got[:0]
  239. tr.AscendLessThan(Int(60), func(a Item) bool {
  240. if a.(Int) > 50 {
  241. return false
  242. }
  243. got = append(got, a)
  244. return true
  245. })
  246. if want := rang(100)[:51]; !reflect.DeepEqual(got, want) {
  247. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  248. }
  249. }
  250. func TestDescendLessOrEqual(t *testing.T) {
  251. tr := New(*btreeDegree)
  252. for _, v := range perm(100) {
  253. tr.ReplaceOrInsert(v)
  254. }
  255. var got []Item
  256. tr.DescendLessOrEqual(Int(40), func(a Item) bool {
  257. got = append(got, a)
  258. return true
  259. })
  260. if want := rangrev(100)[59:]; !reflect.DeepEqual(got, want) {
  261. t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want)
  262. }
  263. got = got[:0]
  264. tr.DescendLessOrEqual(Int(60), func(a Item) bool {
  265. if a.(Int) < 50 {
  266. return false
  267. }
  268. got = append(got, a)
  269. return true
  270. })
  271. if want := rangrev(100)[39:50]; !reflect.DeepEqual(got, want) {
  272. t.Fatalf("descendlessorequal:\n got: %v\nwant: %v", got, want)
  273. }
  274. }
  275. func TestAscendGreaterOrEqual(t *testing.T) {
  276. tr := New(*btreeDegree)
  277. for _, v := range perm(100) {
  278. tr.ReplaceOrInsert(v)
  279. }
  280. var got []Item
  281. tr.AscendGreaterOrEqual(Int(40), func(a Item) bool {
  282. got = append(got, a)
  283. return true
  284. })
  285. if want := rang(100)[40:]; !reflect.DeepEqual(got, want) {
  286. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  287. }
  288. got = got[:0]
  289. tr.AscendGreaterOrEqual(Int(40), func(a Item) bool {
  290. if a.(Int) > 50 {
  291. return false
  292. }
  293. got = append(got, a)
  294. return true
  295. })
  296. if want := rang(100)[40:51]; !reflect.DeepEqual(got, want) {
  297. t.Fatalf("ascendrange:\n got: %v\nwant: %v", got, want)
  298. }
  299. }
  300. func TestDescendGreaterThan(t *testing.T) {
  301. tr := New(*btreeDegree)
  302. for _, v := range perm(100) {
  303. tr.ReplaceOrInsert(v)
  304. }
  305. var got []Item
  306. tr.DescendGreaterThan(Int(40), func(a Item) bool {
  307. got = append(got, a)
  308. return true
  309. })
  310. if want := rangrev(100)[:59]; !reflect.DeepEqual(got, want) {
  311. t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want)
  312. }
  313. got = got[:0]
  314. tr.DescendGreaterThan(Int(40), func(a Item) bool {
  315. if a.(Int) < 50 {
  316. return false
  317. }
  318. got = append(got, a)
  319. return true
  320. })
  321. if want := rangrev(100)[:50]; !reflect.DeepEqual(got, want) {
  322. t.Fatalf("descendgreaterthan:\n got: %v\nwant: %v", got, want)
  323. }
  324. }
  325. const benchmarkTreeSize = 10000
  326. func BenchmarkInsert(b *testing.B) {
  327. b.StopTimer()
  328. insertP := perm(benchmarkTreeSize)
  329. b.StartTimer()
  330. i := 0
  331. for i < b.N {
  332. tr := New(*btreeDegree)
  333. for _, item := range insertP {
  334. tr.ReplaceOrInsert(item)
  335. i++
  336. if i >= b.N {
  337. return
  338. }
  339. }
  340. }
  341. }
  342. func BenchmarkSeek(b *testing.B) {
  343. b.StopTimer()
  344. size := 100000
  345. insertP := perm(size)
  346. tr := New(*btreeDegree)
  347. for _, item := range insertP {
  348. tr.ReplaceOrInsert(item)
  349. }
  350. b.StartTimer()
  351. for i := 0; i < b.N; i++ {
  352. tr.AscendGreaterOrEqual(Int(i%size), func(i Item) bool { return false })
  353. }
  354. }
  355. func BenchmarkDeleteInsert(b *testing.B) {
  356. b.StopTimer()
  357. insertP := perm(benchmarkTreeSize)
  358. tr := New(*btreeDegree)
  359. for _, item := range insertP {
  360. tr.ReplaceOrInsert(item)
  361. }
  362. b.StartTimer()
  363. for i := 0; i < b.N; i++ {
  364. tr.Delete(insertP[i%benchmarkTreeSize])
  365. tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
  366. }
  367. }
  368. func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
  369. b.StopTimer()
  370. insertP := perm(benchmarkTreeSize)
  371. tr := New(*btreeDegree)
  372. for _, item := range insertP {
  373. tr.ReplaceOrInsert(item)
  374. }
  375. tr = tr.Clone()
  376. b.StartTimer()
  377. for i := 0; i < b.N; i++ {
  378. tr.Delete(insertP[i%benchmarkTreeSize])
  379. tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
  380. }
  381. }
  382. func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
  383. b.StopTimer()
  384. insertP := perm(benchmarkTreeSize)
  385. tr := New(*btreeDegree)
  386. for _, item := range insertP {
  387. tr.ReplaceOrInsert(item)
  388. }
  389. b.StartTimer()
  390. for i := 0; i < b.N; i++ {
  391. tr = tr.Clone()
  392. tr.Delete(insertP[i%benchmarkTreeSize])
  393. tr.ReplaceOrInsert(insertP[i%benchmarkTreeSize])
  394. }
  395. }
  396. func BenchmarkDelete(b *testing.B) {
  397. b.StopTimer()
  398. insertP := perm(benchmarkTreeSize)
  399. removeP := perm(benchmarkTreeSize)
  400. b.StartTimer()
  401. i := 0
  402. for i < b.N {
  403. b.StopTimer()
  404. tr := New(*btreeDegree)
  405. for _, v := range insertP {
  406. tr.ReplaceOrInsert(v)
  407. }
  408. b.StartTimer()
  409. for _, item := range removeP {
  410. tr.Delete(item)
  411. i++
  412. if i >= b.N {
  413. return
  414. }
  415. }
  416. if tr.Len() > 0 {
  417. panic(tr.Len())
  418. }
  419. }
  420. }
  421. func BenchmarkGet(b *testing.B) {
  422. b.StopTimer()
  423. insertP := perm(benchmarkTreeSize)
  424. removeP := perm(benchmarkTreeSize)
  425. b.StartTimer()
  426. i := 0
  427. for i < b.N {
  428. b.StopTimer()
  429. tr := New(*btreeDegree)
  430. for _, v := range insertP {
  431. tr.ReplaceOrInsert(v)
  432. }
  433. b.StartTimer()
  434. for _, item := range removeP {
  435. tr.Get(item)
  436. i++
  437. if i >= b.N {
  438. return
  439. }
  440. }
  441. }
  442. }
  443. func BenchmarkGetCloneEachTime(b *testing.B) {
  444. b.StopTimer()
  445. insertP := perm(benchmarkTreeSize)
  446. removeP := perm(benchmarkTreeSize)
  447. b.StartTimer()
  448. i := 0
  449. for i < b.N {
  450. b.StopTimer()
  451. tr := New(*btreeDegree)
  452. for _, v := range insertP {
  453. tr.ReplaceOrInsert(v)
  454. }
  455. b.StartTimer()
  456. for _, item := range removeP {
  457. tr = tr.Clone()
  458. tr.Get(item)
  459. i++
  460. if i >= b.N {
  461. return
  462. }
  463. }
  464. }
  465. }
  466. type byInts []Item
  467. func (a byInts) Len() int {
  468. return len(a)
  469. }
  470. func (a byInts) Less(i, j int) bool {
  471. return a[i].(Int) < a[j].(Int)
  472. }
  473. func (a byInts) Swap(i, j int) {
  474. a[i], a[j] = a[j], a[i]
  475. }
  476. func BenchmarkAscend(b *testing.B) {
  477. arr := perm(benchmarkTreeSize)
  478. tr := New(*btreeDegree)
  479. for _, v := range arr {
  480. tr.ReplaceOrInsert(v)
  481. }
  482. sort.Sort(byInts(arr))
  483. b.ResetTimer()
  484. for i := 0; i < b.N; i++ {
  485. j := 0
  486. tr.Ascend(func(item Item) bool {
  487. if item.(Int) != arr[j].(Int) {
  488. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  489. }
  490. j++
  491. return true
  492. })
  493. }
  494. }
  495. func BenchmarkDescend(b *testing.B) {
  496. arr := perm(benchmarkTreeSize)
  497. tr := New(*btreeDegree)
  498. for _, v := range arr {
  499. tr.ReplaceOrInsert(v)
  500. }
  501. sort.Sort(byInts(arr))
  502. b.ResetTimer()
  503. for i := 0; i < b.N; i++ {
  504. j := len(arr) - 1
  505. tr.Descend(func(item Item) bool {
  506. if item.(Int) != arr[j].(Int) {
  507. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  508. }
  509. j--
  510. return true
  511. })
  512. }
  513. }
  514. func BenchmarkAscendRange(b *testing.B) {
  515. arr := perm(benchmarkTreeSize)
  516. tr := New(*btreeDegree)
  517. for _, v := range arr {
  518. tr.ReplaceOrInsert(v)
  519. }
  520. sort.Sort(byInts(arr))
  521. b.ResetTimer()
  522. for i := 0; i < b.N; i++ {
  523. j := 100
  524. tr.AscendRange(Int(100), arr[len(arr)-100], func(item Item) bool {
  525. if item.(Int) != arr[j].(Int) {
  526. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  527. }
  528. j++
  529. return true
  530. })
  531. if j != len(arr)-100 {
  532. b.Fatalf("expected: %v, got %v", len(arr)-100, j)
  533. }
  534. }
  535. }
  536. func BenchmarkDescendRange(b *testing.B) {
  537. arr := perm(benchmarkTreeSize)
  538. tr := New(*btreeDegree)
  539. for _, v := range arr {
  540. tr.ReplaceOrInsert(v)
  541. }
  542. sort.Sort(byInts(arr))
  543. b.ResetTimer()
  544. for i := 0; i < b.N; i++ {
  545. j := len(arr) - 100
  546. tr.DescendRange(arr[len(arr)-100], Int(100), func(item Item) bool {
  547. if item.(Int) != arr[j].(Int) {
  548. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  549. }
  550. j--
  551. return true
  552. })
  553. if j != 100 {
  554. b.Fatalf("expected: %v, got %v", len(arr)-100, j)
  555. }
  556. }
  557. }
  558. func BenchmarkAscendGreaterOrEqual(b *testing.B) {
  559. arr := perm(benchmarkTreeSize)
  560. tr := New(*btreeDegree)
  561. for _, v := range arr {
  562. tr.ReplaceOrInsert(v)
  563. }
  564. sort.Sort(byInts(arr))
  565. b.ResetTimer()
  566. for i := 0; i < b.N; i++ {
  567. j := 100
  568. k := 0
  569. tr.AscendGreaterOrEqual(Int(100), func(item Item) bool {
  570. if item.(Int) != arr[j].(Int) {
  571. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  572. }
  573. j++
  574. k++
  575. return true
  576. })
  577. if j != len(arr) {
  578. b.Fatalf("expected: %v, got %v", len(arr), j)
  579. }
  580. if k != len(arr)-100 {
  581. b.Fatalf("expected: %v, got %v", len(arr)-100, k)
  582. }
  583. }
  584. }
  585. func BenchmarkDescendLessOrEqual(b *testing.B) {
  586. arr := perm(benchmarkTreeSize)
  587. tr := New(*btreeDegree)
  588. for _, v := range arr {
  589. tr.ReplaceOrInsert(v)
  590. }
  591. sort.Sort(byInts(arr))
  592. b.ResetTimer()
  593. for i := 0; i < b.N; i++ {
  594. j := len(arr) - 100
  595. k := len(arr)
  596. tr.DescendLessOrEqual(arr[len(arr)-100], func(item Item) bool {
  597. if item.(Int) != arr[j].(Int) {
  598. b.Fatalf("mismatch: expected: %v, got %v", arr[j].(Int), item.(Int))
  599. }
  600. j--
  601. k--
  602. return true
  603. })
  604. if j != -1 {
  605. b.Fatalf("expected: %v, got %v", -1, j)
  606. }
  607. if k != 99 {
  608. b.Fatalf("expected: %v, got %v", 99, k)
  609. }
  610. }
  611. }
  612. const cloneTestSize = 10000
  613. func cloneTest(t *testing.T, b *BTree, start int, p []Item, wg *sync.WaitGroup, trees *[]*BTree) {
  614. t.Logf("Starting new clone at %v", start)
  615. *trees = append(*trees, b)
  616. for i := start; i < cloneTestSize; i++ {
  617. b.ReplaceOrInsert(p[i])
  618. if i%(cloneTestSize/5) == 0 {
  619. wg.Add(1)
  620. go cloneTest(t, b.Clone(), i+1, p, wg, trees)
  621. }
  622. }
  623. wg.Done()
  624. }
  625. func TestCloneConcurrentOperations(t *testing.T) {
  626. b := New(*btreeDegree)
  627. trees := []*BTree{}
  628. p := perm(cloneTestSize)
  629. var wg sync.WaitGroup
  630. wg.Add(1)
  631. go cloneTest(t, b, 0, p, &wg, &trees)
  632. wg.Wait()
  633. want := rang(cloneTestSize)
  634. t.Logf("Starting equality checks on %d trees", len(trees))
  635. for i, tree := range trees {
  636. if !reflect.DeepEqual(want, all(tree)) {
  637. t.Errorf("tree %v mismatch", i)
  638. }
  639. }
  640. t.Log("Removing half from first half")
  641. toRemove := rang(cloneTestSize)[cloneTestSize/2:]
  642. for i := 0; i < len(trees)/2; i++ {
  643. tree := trees[i]
  644. wg.Add(1)
  645. go func() {
  646. for _, item := range toRemove {
  647. tree.Delete(item)
  648. }
  649. wg.Done()
  650. }()
  651. }
  652. wg.Wait()
  653. t.Log("Checking all values again")
  654. for i, tree := range trees {
  655. var wantpart []Item
  656. if i < len(trees)/2 {
  657. wantpart = want[:cloneTestSize/2]
  658. } else {
  659. wantpart = want
  660. }
  661. if got := all(tree); !reflect.DeepEqual(wantpart, got) {
  662. t.Errorf("tree %v mismatch, want %v got %v", i, len(want), len(got))
  663. }
  664. }
  665. }
  666. func BenchmarkDeleteAndRestore(b *testing.B) {
  667. items := perm(16392)
  668. b.ResetTimer()
  669. b.Run(`CopyBigFreeList`, func(b *testing.B) {
  670. fl := NewFreeList(16392)
  671. tr := NewWithFreeList(*btreeDegree, fl)
  672. for _, v := range items {
  673. tr.ReplaceOrInsert(v)
  674. }
  675. b.ReportAllocs()
  676. b.ResetTimer()
  677. for i := 0; i < b.N; i++ {
  678. dels := make([]Item, 0, tr.Len())
  679. tr.Ascend(ItemIterator(func(b Item) bool {
  680. dels = append(dels, b)
  681. return true
  682. }))
  683. for _, del := range dels {
  684. tr.Delete(del)
  685. }
  686. // tr is now empty, we make a new empty copy of it.
  687. tr = NewWithFreeList(*btreeDegree, fl)
  688. for _, v := range items {
  689. tr.ReplaceOrInsert(v)
  690. }
  691. }
  692. })
  693. b.Run(`Copy`, func(b *testing.B) {
  694. tr := New(*btreeDegree)
  695. for _, v := range items {
  696. tr.ReplaceOrInsert(v)
  697. }
  698. b.ReportAllocs()
  699. b.ResetTimer()
  700. for i := 0; i < b.N; i++ {
  701. dels := make([]Item, 0, tr.Len())
  702. tr.Ascend(ItemIterator(func(b Item) bool {
  703. dels = append(dels, b)
  704. return true
  705. }))
  706. for _, del := range dels {
  707. tr.Delete(del)
  708. }
  709. // tr is now empty, we make a new empty copy of it.
  710. tr = New(*btreeDegree)
  711. for _, v := range items {
  712. tr.ReplaceOrInsert(v)
  713. }
  714. }
  715. })
  716. b.Run(`ClearBigFreelist`, func(b *testing.B) {
  717. fl := NewFreeList(16392)
  718. tr := NewWithFreeList(*btreeDegree, fl)
  719. for _, v := range items {
  720. tr.ReplaceOrInsert(v)
  721. }
  722. b.ReportAllocs()
  723. b.ResetTimer()
  724. for i := 0; i < b.N; i++ {
  725. tr.Clear(true)
  726. for _, v := range items {
  727. tr.ReplaceOrInsert(v)
  728. }
  729. }
  730. })
  731. b.Run(`Clear`, func(b *testing.B) {
  732. tr := New(*btreeDegree)
  733. for _, v := range items {
  734. tr.ReplaceOrInsert(v)
  735. }
  736. b.ReportAllocs()
  737. b.ResetTimer()
  738. for i := 0; i < b.N; i++ {
  739. tr.Clear(true)
  740. for _, v := range items {
  741. tr.ReplaceOrInsert(v)
  742. }
  743. }
  744. })
  745. }