Merge pull request #26 from emirpasic/btree

Btree
pull/29/head v1.5.0
Emir Pasic 9 years ago committed by GitHub
commit 7f89ed30ec

@ -24,6 +24,7 @@ Implementation of various data structures and algorithms in Go.
- [TreeBidiMap](#treebidimap)
- [Trees](#trees)
- [RedBlackTree](#redblacktree)
- [BTree](#btree)
- [BinaryHeap](#binaryheap)
- [Functions](#functions)
- [Comparator](#comparator)
@ -69,6 +70,7 @@ Containers are either ordered or unordered. All ordered containers provide [stat
| [HashBidiMap](#hashbidimap) | no | no | no | key* |
| [TreeBidiMap](#treebidimap) | yes | yes* | yes | key* |
| [RedBlackTree](#redblacktree) | yes | yes* | no | key |
| [BTree](#btree) | yes | yes* | no | key |
| [BinaryHeap](#binaryheap) | yes | yes* | no | index |
| | | <sub><sup>*reversible</sup></sub> | | <sub><sup>*bidirectional</sup></sub> |
@ -525,11 +527,11 @@ type Tree interface {
A redblack [tree](#trees) is a binary search tree with an extra bit of data per node, its color, which can be either red or black. The extra bit of storage ensures an approximately balanced tree by constraining how nodes are colored from any path from the root to the leaf. Thus, it is a data structure which is a type of self-balancing binary search tree.
The balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time. <small>[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree)</small>
The balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time. <sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree)</sup></sub>
Implements [Tree](#trees) and [IteratorWithKey](#iteratorwithkey) interfaces.
Implements [Tree](#trees) and [ReverseIteratorWithKey](#reverseiteratorwithkey) interfaces.
<center><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Red-black_tree_example.svg/500px-Red-black_tree_example.svg.png" width="400px" height="200px" /></center>
<p align="center"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Red-black_tree_example.svg/500px-Red-black_tree_example.svg.png" width="400px" height="200px" /></p>
```go
package main
@ -550,7 +552,7 @@ func main() {
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(m)
fmt.Println(tree)
//
// RedBlackTree
// │ ┌── 6
@ -564,7 +566,7 @@ func main() {
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(m)
fmt.Println(tree)
//
// RedBlackTree
// │ ┌── 6
@ -587,6 +589,81 @@ func main() {
Extending the red-black tree's functionality has been demonstrated in the following [example](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended.go).
#### BTree
B-tree is a self-balancing tree data structure that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time. The B-tree is a generalization of a binary search tree in that a node can have more than two children.
According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:
- Every node has at most m children.
- Every non-leaf node (except root) has at least ⌈m/2⌉ children.
- The root has at least two children if it is not a leaf node.
- A non-leaf node with k children contains k1 keys.
- All leaves appear in the same level
Each internal nodes keys act as separation values which divide its subtrees. For example, if an internal node has 3 child nodes (or subtrees) then it must have 2 keys: a1 and a2. All values in the leftmost subtree will be less than a1, all values in the middle subtree will be between a1 and a2, and all values in the rightmost subtree will be greater than a2.<sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree)</sub></sup>
Implements [Tree](#trees) and [ReverseIteratorWithKey](#reverseiteratorwithkey) interfaces.
<p align="center"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/B-tree.svg/831px-B-tree.svg.png" width="400px" height="111px" /></p>
```go
package main
import (
"fmt"
"github.com/emirpasic/gods/trees/btree"
)
func main() {
tree := btree.NewWithIntComparator(3) // empty (keys are of type int)
tree.Put(1, "x") // 1->x
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(1, "a") // 1->a, 2->b (in order, replacement)
tree.Put(3, "c") // 1->a, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
tree.Put(7, "g") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)
fmt.Println(tree)
// BTree
// 1
// 2
// 3
// 4
// 5
// 6
// 7
_ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f", "g"} (in order)
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
// BTree
// 1
// 3
// 4
// 5
// 6
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
// Other:
tree.Height() // gets the height of the tree
tree.Left() // gets the left-most (min) node
tree.LeftKey() // get the left-most (min) node's key
tree.LeftValue() // get the left-most (min) node's value
tree.Right() // get the right-most (max) node
tree.RightKey() // get the right-most (max) node's key
tree.RightValue() // get the right-most (max) node's value
}
```
#### BinaryHeap
A binary heap is a [tree](#trees) created using a binary tree. It can be seen as a binary tree with two additional constraints:
@ -596,11 +673,11 @@ A binary heap is a [tree](#trees) created using a binary tree. It can be seen as
A binary heap is a complete binary tree; that is, all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right.
- Heap property:
All nodes are either greater than or equal to or less than or equal to each of its children, according to a comparison predicate defined for the heap. <small>[Wikipedia](http://en.wikipedia.org/wiki/Binary_heap)</small>
All nodes are either greater than or equal to or less than or equal to each of its children, according to a comparison predicate defined for the heap. <sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Binary_heap)</sub></sup>
Implements [Tree](#trees) and [IteratorWithIndex](#iteratorwithindex) interfaces.
Implements [Tree](#trees) and [ReverseIteratorWithIndex](#reverseiteratorwithindex) interfaces.
<center><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Max-Heap.svg/501px-Max-Heap.svg.png" width="300px" height="200px" /></center>
<p align="center"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Max-Heap.svg/501px-Max-Heap.svg.png" width="300px" height="200px" /></p>
```go
package main
@ -1142,7 +1219,11 @@ Thread safety is not a concern of this project, this should be handled at a high
### Testing and Benchmarking
`go test -v -bench . -benchmem -benchtime 1s ./...`
This takes a while, so test within sub-packages:
`go test -run=NO_TEST -bench . -benchmem -benchtime 1s ./...`
<p align="center"><img src="https://cloud.githubusercontent.com/assets/3115942/16892979/5e698d46-4b27-11e6-864b-cb2b865327b6.png" /></p>
### Contributing

@ -0,0 +1,59 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/trees/btree"
)
// BTreeExample to demonstrate basic usage of BTree
func BTreeExample() {
tree := btree.NewWithIntComparator(3) // empty (keys are of type int)
tree.Put(1, "x") // 1->x
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(1, "a") // 1->a, 2->b (in order, replacement)
tree.Put(3, "c") // 1->a, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
tree.Put(7, "g") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)
fmt.Println(tree)
// BTree
// 1
// 2
// 3
// 4
// 5
// 6
// 7
_ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f", "g"} (in order)
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
// BTree
// 1
// 3
// 4
// 5
// 6
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
// Other:
tree.Height() // gets the height of the tree
tree.Left() // gets the left-most (min) node
tree.LeftKey() // get the left-most (min) node's key
tree.LeftValue() // get the left-most (min) node's value
tree.Right() // get the right-most (max) node
tree.RightKey() // get the right-most (max) node's key
tree.RightValue() // get the right-most (max) node's value
}

@ -426,14 +426,155 @@ func TestListIteratorLast(t *testing.T) {
}
}
func BenchmarkList(b *testing.B) {
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
list := New()
for n := 0; n < 1000; n++ {
list.Add(i)
for n := 0; n < size; n++ {
list.Get(n)
}
for !list.Empty() {
list.Remove(0)
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkArrayListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

@ -426,14 +426,155 @@ func TestListIteratorLast(t *testing.T) {
}
}
func BenchmarkList(b *testing.B) {
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
list := New()
for n := 0; n < 1000; n++ {
list.Add(i)
for n := 0; n < size; n++ {
list.Get(n)
}
for !list.Empty() {
list.Remove(0)
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkDoublyLinkedListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

@ -345,14 +345,155 @@ func TestListIteratorFirst(t *testing.T) {
}
}
func BenchmarkList(b *testing.B) {
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
list := New()
for n := 0; n < 1000; n++ {
list.Add(i)
for n := 0; n < size; n++ {
list.Get(n)
}
for !list.Empty() {
list.Remove(0)
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkSinglyLinkedListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

@ -169,14 +169,155 @@ func sameElements(a []interface{}, b []interface{}) bool {
return true
}
func BenchmarkMap(b *testing.B) {
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
m := New()
for n := 0; n < 1000; n++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkHashBidiMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

@ -137,14 +137,155 @@ func sameElements(a []interface{}, b []interface{}) bool {
return true
}
func BenchmarkMap(b *testing.B) {
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
m := New()
for n := 0; n < 1000; n++ {
m.Put(n, n)
for n := 0; n < size; n++ {
m.Get(n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkHashMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

@ -473,14 +473,155 @@ func TestMapIteratorLast(t *testing.T) {
}
}
func BenchmarkMap(b *testing.B) {
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
m := NewWithIntComparators()
for n := 0; n < 1000; n++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkTreeBidiMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

@ -440,14 +440,155 @@ func TestMapIteratorLast(t *testing.T) {
}
}
func BenchmarkMap(b *testing.B) {
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
m := NewWithIntComparator()
for n := 0; n < 1000; n++ {
m.Put(n, n)
for n := 0; n < size; n++ {
m.Get(n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkTreeMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

@ -62,14 +62,155 @@ func TestSetRemove(t *testing.T) {
}
}
func BenchmarkSet(b *testing.B) {
func benchmarkContains(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
set := New()
for n := 0; n < 1000; n++ {
set.Add(i)
for n := 0; n < size; n++ {
set.Contains(n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkAdd(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Remove(n)
}
}
}
func BenchmarkHashSetContains100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetAdd100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetRemove100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}

@ -327,14 +327,155 @@ func TestSetIteratorLast(t *testing.T) {
}
}
func BenchmarkSet(b *testing.B) {
func benchmarkContains(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
set := NewWithIntComparator()
for n := 0; n < 1000; n++ {
set.Add(i)
for n := 0; n < size; n++ {
set.Contains(n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkAdd(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Remove(n)
}
}
}
func BenchmarkTreeSetContains100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetAdd100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetRemove100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}

@ -231,14 +231,103 @@ func TestStackIteratorLast(t *testing.T) {
}
}
func BenchmarkStack(b *testing.B) {
func benchmarkPush(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
stack := New()
for n := 0; n < 1000; n++ {
stack.Push(i)
for n := 0; n < size; n++ {
stack.Push(n)
}
for !stack.Empty() {
}
}
func benchmarkPop(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Pop()
}
}
}
func BenchmarkArrayStackPop100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPush100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}

@ -147,14 +147,103 @@ func TestStackIteratorFirst(t *testing.T) {
}
}
func BenchmarkStack(b *testing.B) {
func benchmarkPush(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
stack := New()
for n := 0; n < 1000; n++ {
stack.Push(i)
for n := 0; n < size; n++ {
stack.Push(n)
}
for !stack.Empty() {
}
}
func benchmarkPop(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Pop()
}
}
}
func BenchmarkLinkedListStackPop100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPush100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}

@ -246,15 +246,103 @@ func TestBinaryHeapIteratorLast(t *testing.T) {
}
}
func BenchmarkBinaryHeap(b *testing.B) {
func benchmarkPush(b *testing.B, heap *Heap, size int) {
for i := 0; i < b.N; i++ {
heap := NewWithIntComparator()
for n := 0; n < 1000; n++ {
heap.Push(i)
for n := 0; n < size; n++ {
heap.Push(n)
}
for !heap.Empty() {
}
}
func benchmarkPop(b *testing.B, heap *Heap, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
heap.Pop()
}
}
}
func BenchmarkBinaryHeapPop100(b *testing.B) {
b.StopTimer()
size := 100
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop1000(b *testing.B) {
b.StopTimer()
size := 1000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop10000(b *testing.B) {
b.StopTimer()
size := 10000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop100000(b *testing.B) {
b.StopTimer()
size := 100000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPush100(b *testing.B) {
b.StopTimer()
size := 100
heap := NewWithIntComparator()
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush1000(b *testing.B) {
b.StopTimer()
size := 1000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush10000(b *testing.B) {
b.StopTimer()
size := 10000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush100000(b *testing.B) {
b.StopTimer()
size := 100000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}

@ -0,0 +1,574 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package btree implements a B tree.
//
// According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:
// - Every node has at most m children.
// - Every non-leaf node (except root) has at least ⌈m/2⌉ children.
// - The root has at least two children if it is not a leaf node.
// - A non-leaf node with k children contains k1 keys.
// - All leaves appear in the same level
//
// Structure is not thread safe.
//
// References: https://en.wikipedia.org/wiki/B-tree
package btree
import (
"bytes"
"fmt"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertTreeImplementation() {
var _ trees.Tree = (*Tree)(nil)
}
// Tree holds elements of the B-tree
type Tree struct {
Root *Node // Root node
Comparator utils.Comparator // Key comparator
size int // Total number of keys in the tree
m int // order (maximum number of children)
}
// Node is a single element within the tree
type Node struct {
Parent *Node
Entries []*Entry // Contained keys in node
Children []*Node // Children nodes
}
// Entry represents the key-value pair contained within nodes
type Entry struct {
Key interface{}
Value interface{}
}
// NewWith instantiates a B-tree with the order (maximum number of children) and a custom key comparator.
func NewWith(order int, comparator utils.Comparator) *Tree {
if order < 3 {
panic("Invalid order, should be at least 3")
}
return &Tree{m: order, Comparator: comparator}
}
// NewWithIntComparator instantiates a B-tree with the order (maximum number of children) and the IntComparator, i.e. keys are of type int.
func NewWithIntComparator(order int) *Tree {
return NewWith(order, utils.IntComparator)
}
// NewWithStringComparator instantiates a B-tree with the order (maximum number of children) and the StringComparator, i.e. keys are of type string.
func NewWithStringComparator(order int) *Tree {
return NewWith(order, utils.StringComparator)
}
// Put inserts key-value pair node into the tree.
// If key already exists, then its value is updated with the new value.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key interface{}, value interface{}) {
entry := &Entry{Key: key, Value: value}
if tree.Root == nil {
tree.Root = &Node{Entries: []*Entry{entry}, Children: []*Node{}}
tree.size++
return
}
if tree.insert(tree.Root, entry) {
tree.size++
}
}
// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Get(key interface{}) (value interface{}, found bool) {
node, index, found := tree.searchRecursively(tree.Root, key)
if found {
return node.Entries[index].Value, true
}
return nil, false
}
// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key interface{}) {
node, index, found := tree.searchRecursively(tree.Root, key)
if found {
tree.delete(node, index)
tree.size--
}
}
// Empty returns true if tree does not contain any nodes
func (tree *Tree) Empty() bool {
return tree.size == 0
}
// Size returns number of nodes in the tree.
func (tree *Tree) Size() int {
return tree.size
}
// Keys returns all keys in-order
func (tree *Tree) Keys() []interface{} {
keys := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
keys[i] = it.Key()
}
return keys
}
// Values returns all values in-order based on the key.
func (tree *Tree) Values() []interface{} {
values := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
values[i] = it.Value()
}
return values
}
// Clear removes all nodes from the tree.
func (tree *Tree) Clear() {
tree.Root = nil
tree.size = 0
}
// Height returns the height of the tree.
func (tree *Tree) Height() int {
return tree.Root.height()
}
// Left returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() *Node {
return tree.left(tree.Root)
}
// LeftKey returns the left-most (min) key or nil if tree is empty.
func (tree *Tree) LeftKey() interface{} {
if left := tree.Left(); left != nil {
return left.Entries[0].Key
}
return nil
}
// LeftValue returns the left-most value or nil if tree is empty.
func (tree *Tree) LeftValue() interface{} {
if left := tree.Left(); left != nil {
return left.Entries[0].Value
}
return nil
}
// Right returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() *Node {
return tree.right(tree.Root)
}
// RightKey returns the right-most (max) key or nil if tree is empty.
func (tree *Tree) RightKey() interface{} {
if right := tree.Right(); right != nil {
return right.Entries[len(right.Entries)-1].Key
}
return nil
}
// RightValue returns the right-most value or nil if tree is empty.
func (tree *Tree) RightValue() interface{} {
if right := tree.Right(); right != nil {
return right.Entries[len(right.Entries)-1].Value
}
return nil
}
// String returns a string representation of container (for debugging purposes)
func (tree *Tree) String() string {
var buffer bytes.Buffer
buffer.WriteString("BTree\n")
if !tree.Empty() {
tree.output(&buffer, tree.Root, 0, true)
}
return buffer.String()
}
func (entry *Entry) String() string {
return fmt.Sprintf("%v", entry.Key)
}
func (tree *Tree) output(buffer *bytes.Buffer, node *Node, level int, isTail bool) {
for e := 0; e < len(node.Entries)+1; e++ {
if e < len(node.Children) {
tree.output(buffer, node.Children[e], level+1, true)
}
if e < len(node.Entries) {
buffer.WriteString(strings.Repeat(" ", level))
buffer.WriteString(fmt.Sprintf("%v", node.Entries[e].Key) + "\n")
}
}
}
func (node *Node) height() int {
height := 0
for ; node != nil; node = node.Children[0] {
height++
if len(node.Children) == 0 {
break
}
}
return height
}
func (tree *Tree) isLeaf(node *Node) bool {
return len(node.Children) == 0
}
func (tree *Tree) isFull(node *Node) bool {
return len(node.Entries) == tree.maxEntries()
}
func (tree *Tree) shouldSplit(node *Node) bool {
return len(node.Entries) > tree.maxEntries()
}
func (tree *Tree) maxChildren() int {
return tree.m
}
func (tree *Tree) minChildren() int {
return (tree.m + 1) / 2 // ceil(m/2)
}
func (tree *Tree) maxEntries() int {
return tree.maxChildren() - 1
}
func (tree *Tree) minEntries() int {
return tree.minChildren() - 1
}
func (tree *Tree) middle() int {
return (tree.m - 1) / 2 // "-1" to favor right nodes to have more keys when splitting
}
// search searches only within the single node among its entries
func (tree *Tree) search(node *Node, key interface{}) (index int, found bool) {
low, high := 0, len(node.Entries)-1
var mid int
for low <= high {
mid = (high + low) / 2
compare := tree.Comparator(key, node.Entries[mid].Key)
switch {
case compare > 0:
low = mid + 1
case compare < 0:
high = mid - 1
case compare == 0:
return mid, true
}
}
return low, false
}
// searchRecursively searches recursively down the tree starting at the startNode
func (tree *Tree) searchRecursively(startNode *Node, key interface{}) (node *Node, index int, found bool) {
if tree.Empty() {
return nil, -1, false
}
node = startNode
for {
index, found = tree.search(node, key)
if found {
return node, index, true
}
if tree.isLeaf(node) {
return nil, -1, false
}
node = node.Children[index]
}
}
func (tree *Tree) insert(node *Node, entry *Entry) (inserted bool) {
if tree.isLeaf(node) {
return tree.insertIntoLeaf(node, entry)
}
return tree.insertIntoInternal(node, entry)
}
func (tree *Tree) insertIntoLeaf(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry.Key)
if found {
node.Entries[insertPosition] = entry
return false
}
// Insert entry's key in the middle of the node
node.Entries = append(node.Entries, nil)
copy(node.Entries[insertPosition+1:], node.Entries[insertPosition:])
node.Entries[insertPosition] = entry
tree.split(node)
return true
}
func (tree *Tree) insertIntoInternal(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry.Key)
if found {
node.Entries[insertPosition] = entry
return false
}
return tree.insert(node.Children[insertPosition], entry)
}
func (tree *Tree) split(node *Node) {
if !tree.shouldSplit(node) {
return
}
if node == tree.Root {
tree.splitRoot()
return
}
tree.splitNonRoot(node)
}
func (tree *Tree) splitNonRoot(node *Node) {
middle := tree.middle()
parent := node.Parent
left := &Node{Entries: append([]*Entry(nil), node.Entries[:middle]...), Parent: parent}
right := &Node{Entries: append([]*Entry(nil), node.Entries[middle+1:]...), Parent: parent}
// Move children from the node to be split into left and right nodes
if !tree.isLeaf(node) {
left.Children = append([]*Node(nil), node.Children[:middle+1]...)
right.Children = append([]*Node(nil), node.Children[middle+1:]...)
setParent(left.Children, left)
setParent(right.Children, right)
}
insertPosition, _ := tree.search(parent, node.Entries[middle].Key)
// Insert middle key into parent
parent.Entries = append(parent.Entries, nil)
copy(parent.Entries[insertPosition+1:], parent.Entries[insertPosition:])
parent.Entries[insertPosition] = node.Entries[middle]
// Set child left of inserted key in parent to the created left node
parent.Children[insertPosition] = left
// Set child right of inserted key in parent to the created right node
parent.Children = append(parent.Children, nil)
copy(parent.Children[insertPosition+2:], parent.Children[insertPosition+1:])
parent.Children[insertPosition+1] = right
tree.split(parent)
}
func (tree *Tree) splitRoot() {
middle := tree.middle()
left := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[:middle]...)}
right := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[middle+1:]...)}
// Move children from the node to be split into left and right nodes
if !tree.isLeaf(tree.Root) {
left.Children = append([]*Node(nil), tree.Root.Children[:middle+1]...)
right.Children = append([]*Node(nil), tree.Root.Children[middle+1:]...)
setParent(left.Children, left)
setParent(right.Children, right)
}
// Root is a node with one entry and two children (left and right)
newRoot := &Node{
Entries: []*Entry{tree.Root.Entries[middle]},
Children: []*Node{left, right},
}
left.Parent = newRoot
right.Parent = newRoot
tree.Root = newRoot
}
func setParent(nodes []*Node, parent *Node) {
for _, node := range nodes {
node.Parent = parent
}
}
func (tree *Tree) left(node *Node) *Node {
if tree.Empty() {
return nil
}
current := node
for {
if tree.isLeaf(current) {
return current
}
current = current.Children[0]
}
}
func (tree *Tree) right(node *Node) *Node {
if tree.Empty() {
return nil
}
current := node
for {
if tree.isLeaf(current) {
return current
}
current = current.Children[len(current.Children)-1]
}
}
// leftSibling returns the node's left sibling and child index (in parent) if it exists, otherwise (nil,-1)
// key is any of keys in node (could even be deleted).
func (tree *Tree) leftSibling(node *Node, key interface{}) (*Node, int) {
if node.Parent != nil {
index, _ := tree.search(node.Parent, key)
index--
if index >= 0 && index < len(node.Parent.Children) {
return node.Parent.Children[index], index
}
}
return nil, -1
}
// rightSibling returns the node's right sibling and child index (in parent) if it exists, otherwise (nil,-1)
// key is any of keys in node (could even be deleted).
func (tree *Tree) rightSibling(node *Node, key interface{}) (*Node, int) {
if node.Parent != nil {
index, _ := tree.search(node.Parent, key)
index++
if index < len(node.Parent.Children) {
return node.Parent.Children[index], index
}
}
return nil, -1
}
// delete deletes an entry in node at entries' index
// ref.: https://en.wikipedia.org/wiki/B-tree#Deletion
func (tree *Tree) delete(node *Node, index int) {
// deleting from a leaf node
if tree.isLeaf(node) {
deletedKey := node.Entries[index].Key
tree.deleteEntry(node, index)
tree.rebalance(node, deletedKey)
if len(tree.Root.Entries) == 0 {
tree.Root = nil
}
return
}
// deleting from an internal node
leftLargestNode := tree.right(node.Children[index]) // largest node in the left sub-tree (assumed to exist)
leftLargestEntryIndex := len(leftLargestNode.Entries) - 1
node.Entries[index] = leftLargestNode.Entries[leftLargestEntryIndex]
deletedKey := leftLargestNode.Entries[leftLargestEntryIndex].Key
tree.deleteEntry(leftLargestNode, leftLargestEntryIndex)
tree.rebalance(leftLargestNode, deletedKey)
}
// rebalance rebalances the tree after deletion if necessary and returns true, otherwise false.
// Note that we first delete the entry and then call rebalance, thus the passed deleted key as reference.
func (tree *Tree) rebalance(node *Node, deletedKey interface{}) {
// check if rebalancing is needed
if node == nil || len(node.Entries) >= tree.minEntries() {
return
}
// try to borrow from left sibling
leftSibling, leftSiblingIndex := tree.leftSibling(node, deletedKey)
if leftSibling != nil && len(leftSibling.Entries) > tree.minEntries() {
// rotate right
node.Entries = append([]*Entry{node.Parent.Entries[leftSiblingIndex]}, node.Entries...) // prepend parent's separator entry to node's entries
node.Parent.Entries[leftSiblingIndex] = leftSibling.Entries[len(leftSibling.Entries)-1]
tree.deleteEntry(leftSibling, len(leftSibling.Entries)-1)
if !tree.isLeaf(leftSibling) {
leftSiblingRightMostChild := leftSibling.Children[len(leftSibling.Children)-1]
leftSiblingRightMostChild.Parent = node
node.Children = append([]*Node{leftSiblingRightMostChild}, node.Children...)
tree.deleteChild(leftSibling, len(leftSibling.Children)-1)
}
return
}
// try to borrow from right sibling
rightSibling, rightSiblingIndex := tree.rightSibling(node, deletedKey)
if rightSibling != nil && len(rightSibling.Entries) > tree.minEntries() {
// rotate left
node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) // append parent's separator entry to node's entries
node.Parent.Entries[rightSiblingIndex-1] = rightSibling.Entries[0]
tree.deleteEntry(rightSibling, 0)
if !tree.isLeaf(rightSibling) {
rightSiblingLeftMostChild := rightSibling.Children[0]
rightSiblingLeftMostChild.Parent = node
node.Children = append(node.Children, rightSiblingLeftMostChild)
tree.deleteChild(rightSibling, 0)
}
return
}
// merge with siblings
if rightSibling != nil {
// merge with right sibling
node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1])
node.Entries = append(node.Entries, rightSibling.Entries...)
deletedKey = node.Parent.Entries[rightSiblingIndex-1].Key
tree.deleteEntry(node.Parent, rightSiblingIndex-1)
tree.appendChildren(node.Parent.Children[rightSiblingIndex], node)
tree.deleteChild(node.Parent, rightSiblingIndex)
} else if leftSibling != nil {
// merge with left sibling
entries := append([]*Entry(nil), leftSibling.Entries...)
entries = append(entries, node.Parent.Entries[leftSiblingIndex])
node.Entries = append(entries, node.Entries...)
deletedKey = node.Parent.Entries[leftSiblingIndex].Key
tree.deleteEntry(node.Parent, leftSiblingIndex)
tree.prependChildren(node.Parent.Children[leftSiblingIndex], node)
tree.deleteChild(node.Parent, leftSiblingIndex)
}
// make the merged node the root if its parent was the root and the root is empty
if node.Parent == tree.Root && len(tree.Root.Entries) == 0 {
tree.Root = node
node.Parent = nil
return
}
// parent might underflow, so try to rebalance if necessary
tree.rebalance(node.Parent, deletedKey)
}
func (tree *Tree) prependChildren(fromNode *Node, toNode *Node) {
children := append([]*Node(nil), fromNode.Children...)
toNode.Children = append(children, toNode.Children...)
setParent(fromNode.Children, toNode)
}
func (tree *Tree) appendChildren(fromNode *Node, toNode *Node) {
toNode.Children = append(toNode.Children, fromNode.Children...)
setParent(fromNode.Children, toNode)
}
func (tree *Tree) deleteEntry(node *Node, index int) {
copy(node.Entries[index:], node.Entries[index+1:])
node.Entries[len(node.Entries)-1] = nil
node.Entries = node.Entries[:len(node.Entries)-1]
}
func (tree *Tree) deleteChild(node *Node, index int) {
if index >= len(node.Children) {
return
}
copy(node.Children[index:], node.Children[index+1:])
node.Children[len(node.Children)-1] = nil
node.Children = node.Children[:len(node.Children)-1]
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,193 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package btree
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
tree *Tree
node *Node
entry *Entry
position position
}
type position byte
const (
begin, between, end position = 0, 1, 2
)
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() Iterator {
return Iterator{tree: tree, node: nil, position: begin}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
// If already at end, go to end
if iterator.position == end {
goto end
}
// If at beginning, get the left-most entry in the tree
if iterator.position == begin {
left := iterator.tree.Left()
if left == nil {
goto end
}
iterator.node = left
iterator.entry = left.Entries[0]
goto between
}
{
// Find current entry position in current node
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Try to go down to the child right of the current entry
if e+1 < len(iterator.node.Children) {
iterator.node = iterator.node.Children[e+1]
// Try to go down to the child left of the current node
for len(iterator.node.Children) > 0 {
iterator.node = iterator.node.Children[0]
}
// Return the left-most entry
iterator.entry = iterator.node.Entries[0]
goto between
}
// Above assures that we have reached a leaf node, so return the next entry in current node (if any)
if e+1 < len(iterator.node.Entries) {
iterator.entry = iterator.node.Entries[e+1]
goto between
}
}
// Reached leaf node and there are no entries to the right of the current entry, so go up to the parent
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
// Find next entry position in current node (note: search returns the first equal or bigger than entry)
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Check that there is a next entry position in current node
if e < len(iterator.node.Entries) {
iterator.entry = iterator.node.Entries[e]
goto between
}
}
end:
iterator.End()
return false
between:
iterator.position = between
return true
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
// If already at beginning, go to begin
if iterator.position == begin {
goto begin
}
// If at end, get the right-most entry in the tree
if iterator.position == end {
right := iterator.tree.Right()
if right == nil {
goto begin
}
iterator.node = right
iterator.entry = right.Entries[len(right.Entries)-1]
goto between
}
{
// Find current entry position in current node
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Try to go down to the child left of the current entry
if e < len(iterator.node.Children) {
iterator.node = iterator.node.Children[e]
// Try to go down to the child right of the current node
for len(iterator.node.Children) > 0 {
iterator.node = iterator.node.Children[len(iterator.node.Children)-1]
}
// Return the right-most entry
iterator.entry = iterator.node.Entries[len(iterator.node.Entries)-1]
goto between
}
// Above assures that we have reached a leaf node, so return the previous entry in current node (if any)
if e-1 >= 0 {
iterator.entry = iterator.node.Entries[e-1]
goto between
}
}
// Reached leaf node and there are no entries to the left of the current entry, so go up to the parent
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
// Find previous entry position in current node (note: search returns the first equal or bigger than entry)
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Check that there is a previous entry position in current node
if e-1 >= 0 {
iterator.entry = iterator.node.Entries[e-1]
goto between
}
}
begin:
iterator.Begin()
return false
between:
iterator.position = between
return true
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.entry.Value
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
return iterator.entry.Key
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.node = nil
iterator.position = begin
iterator.entry = nil
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.node = nil
iterator.position = end
iterator.entry = nil
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

@ -13,7 +13,6 @@ package redblacktree
import (
"fmt"
"github.com/emirpasic/gods/stacks/linkedliststack"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
)
@ -153,8 +152,9 @@ func (tree *Tree) Size() int {
// Keys returns all keys in-order
func (tree *Tree) Keys() []interface{} {
keys := make([]interface{}, tree.size)
for i, node := range tree.inOrder() {
keys[i] = node.Key
it := tree.Iterator()
for i := 0; it.Next(); i++ {
keys[i] = it.Key()
}
return keys
}
@ -162,8 +162,9 @@ func (tree *Tree) Keys() []interface{} {
// Values returns all values in-order based on the key.
func (tree *Tree) Values() []interface{} {
values := make([]interface{}, tree.size)
for i, node := range tree.inOrder() {
values[i] = node.Value
it := tree.Iterator()
for i := 0; it.Next(); i++ {
values[i] = it.Value()
}
return values
}
@ -267,35 +268,6 @@ func (node *Node) String() string {
return fmt.Sprintf("%v", node.Key)
}
// Returns all nodes in order
func (tree *Tree) inOrder() []*Node {
nodes := make([]*Node, tree.size)
if tree.size > 0 {
current := tree.Root
stack := linkedliststack.New()
done := false
count := 0
for !done {
if current != nil {
stack.Push(current)
current = current.Left
} else {
if !stack.Empty() {
currentPop, _ := stack.Pop()
current = currentPop.(*Node)
nodes[count] = current
count++
current = current.Right
} else {
done = true
}
}
}
}
return nodes
}
// String returns a string representation of container
func output(node *Node, prefix string, isTail bool, str *string) {
if node.Right != nil {
newPrefix := prefix

@ -557,14 +557,155 @@ func TestRedBlackTreeIteratorLast(t *testing.T) {
}
}
func BenchmarkRedBlackTree(b *testing.B) {
func benchmarkGet(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
tree := NewWithIntComparator()
for n := 0; n < 1000; n++ {
tree.Put(n, n)
for n := 0; n < size; n++ {
tree.Get(n)
}
for n := 0; n < 1000; n++ {
}
}
func benchmarkPut(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Remove(n)
}
}
}
func BenchmarkRedBlackTreeGet100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreePut100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreeRemove100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}

Loading…
Cancel
Save