- btree put fixes

pull/26/head
Emir Pasic 9 years ago
parent eecaef5625
commit 2df9ce1ab5

@ -26,7 +26,7 @@ type Tree struct {
Root *Node // Root node
Comparator utils.Comparator // Key comparator
size int // Total number of keys in the tree
m int // Knuth order (maximum number of children)
m int // order (maximum number of children)
}
// Node is a single element within the tree
@ -42,7 +42,7 @@ type Entry struct {
Value interface{}
}
// NewWith instantiates a B-tree with the Knuth order (maximum number of children) and a custom key comparator.
// 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 < 2 {
panic("Invalid order, should be at least 2")
@ -50,12 +50,12 @@ func NewWith(order int, comparator utils.Comparator) *Tree {
return &Tree{m: order, Comparator: comparator}
}
// NewWithIntComparator instantiates a B-tree with the Knuth order (maximum number of children) and the IntComparator, i.e. keys are of type int.
// 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 Knuth order (maximum number of children) and the StringComparator, i.e. keys are of type string.
// 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)
}
@ -81,7 +81,20 @@ func (tree *Tree) Put(key interface{}, value interface{}) {
// 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) {
return nil, false
if tree.Empty() {
return nil, false
}
node := tree.Root
for {
index, found := tree.search(node, key)
if found {
return node.Entries[index].Value, true
}
if tree.isLeaf(node) {
return nil, false
}
node = node.Children[index]
}
}
// Remove remove the node from the tree by key.
@ -138,7 +151,6 @@ func (entry *Entry) String() string {
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) {
buffer.WriteString(strings.Repeat(" ", level))
tree.output(buffer, node.Children[e], level+1, true)
}
if e < len(node.Entries) {
@ -183,12 +195,12 @@ func (tree *Tree) middle() int {
return (tree.m - 1) / 2 // "-1" to favor right nodes to have more keys when splitting
}
func (tree *Tree) search(node *Node, entry *Entry) (index int, found bool) {
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(entry.Key, node.Entries[mid].Key)
compare := tree.Comparator(key, node.Entries[mid].Key)
switch {
case compare > 0:
low = mid + 1
@ -209,11 +221,12 @@ func (tree *Tree) insert(node *Node, entry *Entry) (inserted bool) {
}
func (tree *Tree) insertIntoLeaf(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry)
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
@ -222,7 +235,7 @@ func (tree *Tree) insertIntoLeaf(node *Node, entry *Entry) (inserted bool) {
}
func (tree *Tree) insertIntoInternal(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry)
insertPosition, found := tree.search(node, entry.Key)
if found {
node.Entries[insertPosition] = entry
return false
@ -246,22 +259,30 @@ func (tree *Tree) split(node *Node) {
func (tree *Tree) splitNonRoot(node *Node) {
middle := tree.middle()
parent := node.Parent
if node.Parent == nil {
panic("test") //TODO
}
left := &Node{Entries: node.Entries[:middle], Parent: parent}
right := &Node{Entries: node.Entries[middle+1:], Parent: 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 = node.Children[:middle+1]
right.Children = node.Children[middle+1:]
}
insertPosition, _ := tree.search(parent, node.Entries[middle])
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
@ -272,14 +293,16 @@ func (tree *Tree) splitNonRoot(node *Node) {
func (tree *Tree) splitRoot() {
middle := tree.middle()
left := &Node{Entries: tree.Root.Entries[:middle]}
right := &Node{Entries: tree.Root.Entries[middle+1:]}
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 = tree.Root.Children[:middle+1]
right.Children = tree.Root.Children[middle+1:]
}
// 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},

@ -5,194 +5,279 @@
package btree
import (
_ "fmt"
"fmt"
"testing"
)
func TestBTree_search(t *testing.T) {
{
tree := NewWithIntComparator(3)
tree.Root = &Node{Entries: []*Entry{}, Children: make([]*Node, 0)}
tests := [][]interface{}{
{0, 0, false},
}
for _, test := range tests {
index, found := tree.search(tree.Root, &Entry{test[0], nil})
if actualValue, expectedValue := index, test[1]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := found, test[2]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestBTreeGet1(t *testing.T) {
tree := NewWithIntComparator(3)
tree.Put(1, "a")
tree.Put(2, "b")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tests := [][]interface{}{
{0, nil, false},
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
{
tree := NewWithIntComparator(3)
tree.Root = &Node{Entries: []*Entry{{2, 0}, {4, 1}, {6, 2}}, Children: []*Node{}}
tests := [][]interface{}{
{0, 0, false},
{1, 0, false},
{2, 0, true},
{3, 1, false},
{4, 1, true},
{5, 2, false},
{6, 2, true},
{7, 3, false},
}
for _, test := range tests {
index, found := tree.search(tree.Root, &Entry{test[0], nil})
if actualValue, expectedValue := index, test[1]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := found, test[2]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
for _, test := range tests {
if value, found := tree.Get(test[0]); value != test[1] || found != test[2] {
t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2])
}
}
}
func TestBTree_insert1(t *testing.T) {
func TestBTreeGet2(t *testing.T) {
//tree := NewWithIntComparator(3)
//tree.Put(7, "g")
//tree.Put(9, "i")
//tree.Put(10, "j")
//tree.Put(6, "f")
//tree.Put(3, "c")
//tree.Put(4, "d")
//tree.Put(5, "e")
//tree.Put(8, "h")
//tree.Put(2, "b")
////tree.Put(1, "a")
//fmt.Println(tree)
//
//tests := [][]interface{}{
// {0, nil, false},
// {1, "a", true},
// {2, "b", true},
// {3, "c", true},
// {4, "d", true},
// {5, "e", true},
// {6, "f", true},
// {7, "g", true},
// {8, "h", true},
// {9, "i", true},
// {10, "j", true},
// {11, nil, false},
//}
//
//for _, test := range tests {
// if value, found := tree.Get(test[0]); value != test[1] || found != test[2] {
// t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2])
// }
//}
}
func TestBTreePut1(t *testing.T) {
// https://upload.wikimedia.org/wikipedia/commons/3/33/B_tree_insertion_example.png
tree := NewWithIntComparator(3)
assertValidTree(t, tree, 0)
tree.Put(1, 0)
assertValidTree(t, tree, 1)
assertValidTreeNode(t, tree.Root, 1, 0, []int{1})
assertValidTreeNode(t, tree.Root, 1, 0, []int{1}, false)
tree.Put(2, 1)
assertValidTree(t, tree, 2)
assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2})
assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false)
tree.Put(3, 2)
assertValidTree(t, tree, 3)
assertValidTreeNode(t, tree.Root, 1, 2, []int{2})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1})
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3})
assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)
tree.Put(4, 2)
assertValidTree(t, tree, 4)
assertValidTreeNode(t, tree.Root, 1, 2, []int{2})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1})
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4})
assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true)
tree.Put(5, 2)
assertValidTree(t, tree, 5)
assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1})
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3})
assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{5})
assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)
assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{5}, true)
tree.Put(6, 2)
assertValidTree(t, tree, 6)
assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1})
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3})
assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6})
assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)
assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true)
tree.Put(7, 2)
assertValidTree(t, tree, 7)
assertValidTreeNode(t, tree.Root, 1, 2, []int{4})
assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2})
assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6})
assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1})
assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3})
assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5})
assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7})
assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true)
}
func TestBTree_insert2(t *testing.T) {
func TestBTreePut2(t *testing.T) {
tree := NewWithIntComparator(4)
assertValidTree(t, tree, 0)
tree.Put(0, 0)
assertValidTree(t, tree, 1)
assertValidTreeNode(t, tree.Root, 1, 0, []int{0})
assertValidTreeNode(t, tree.Root, 1, 0, []int{0}, false)
tree.Put(2, 2)
assertValidTree(t, tree, 2)
assertValidTreeNode(t, tree.Root, 2, 0, []int{0, 2})
assertValidTreeNode(t, tree.Root, 2, 0, []int{0, 2}, false)
tree.Put(1, 1)
assertValidTree(t, tree, 3)
assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2})
assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false)
tree.Put(1, 1)
assertValidTree(t, tree, 3)
assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2})
assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false)
tree.Put(3, 3)
assertValidTree(t, tree, 4)
assertValidTreeNode(t, tree.Root, 1, 2, []int{1})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0})
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{2, 3})
assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{2, 3}, true)
tree.Put(4, 4)
assertValidTree(t, tree, 5)
assertValidTreeNode(t, tree.Root, 1, 2, []int{1})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0})
assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{2, 3, 4})
assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)
assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{2, 3, 4}, true)
tree.Put(5, 5)
assertValidTree(t, tree, 6)
assertValidTreeNode(t, tree.Root, 2, 3, []int{1, 3})
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0})
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2})
assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{4, 5})
assertValidTreeNode(t, tree.Root, 2, 3, []int{1, 3}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true)
assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{4, 5}, true)
}
func TestBTree_insert3(t *testing.T) {
func TestBTreePut3(t *testing.T) {
// http://www.geeksforgeeks.org/b-tree-set-1-insert-2/
tree := NewWithIntComparator(6)
assertValidTree(t, tree, 0)
tree.Put(10, 0)
assertValidTree(t, tree, 1)
assertValidTreeNode(t, tree.Root, 1, 0, []int{10})
assertValidTreeNode(t, tree.Root, 1, 0, []int{10}, false)
tree.Put(20, 1)
assertValidTree(t, tree, 2)
assertValidTreeNode(t, tree.Root, 2, 0, []int{10, 20})
assertValidTreeNode(t, tree.Root, 2, 0, []int{10, 20}, false)
tree.Put(30, 2)
assertValidTree(t, tree, 3)
assertValidTreeNode(t, tree.Root, 3, 0, []int{10, 20, 30})
assertValidTreeNode(t, tree.Root, 3, 0, []int{10, 20, 30}, false)
tree.Put(40, 3)
assertValidTree(t, tree, 4)
assertValidTreeNode(t, tree.Root, 4, 0, []int{10, 20, 30, 40})
assertValidTreeNode(t, tree.Root, 4, 0, []int{10, 20, 30, 40}, false)
tree.Put(50, 4)
assertValidTree(t, tree, 5)
assertValidTreeNode(t, tree.Root, 5, 0, []int{10, 20, 30, 40, 50})
assertValidTreeNode(t, tree.Root, 5, 0, []int{10, 20, 30, 40, 50}, false)
tree.Put(60, 5)
assertValidTree(t, tree, 6)
assertValidTreeNode(t, tree.Root, 1, 2, []int{30})
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20})
assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{40, 50, 60})
assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)
assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{40, 50, 60}, true)
tree.Put(70, 6)
assertValidTree(t, tree, 7)
assertValidTreeNode(t, tree.Root, 1, 2, []int{30})
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20})
assertValidTreeNode(t, tree.Root.Children[1], 4, 0, []int{40, 50, 60, 70})
assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)
assertValidTreeNode(t, tree.Root.Children[1], 4, 0, []int{40, 50, 60, 70}, true)
tree.Put(80, 7)
assertValidTree(t, tree, 8)
assertValidTreeNode(t, tree.Root, 1, 2, []int{30})
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20})
assertValidTreeNode(t, tree.Root.Children[1], 5, 0, []int{40, 50, 60, 70, 80})
assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)
assertValidTreeNode(t, tree.Root.Children[1], 5, 0, []int{40, 50, 60, 70, 80}, true)
tree.Put(90, 8)
assertValidTree(t, tree, 9)
assertValidTreeNode(t, tree.Root, 2, 3, []int{30, 60})
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20})
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{40, 50})
assertValidTreeNode(t, tree.Root.Children[2], 3, 0, []int{70, 80, 90})
assertValidTreeNode(t, tree.Root, 2, 3, []int{30, 60}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)
assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{40, 50}, true)
assertValidTreeNode(t, tree.Root.Children[2], 3, 0, []int{70, 80, 90}, true)
}
func TestBTreePut4(t *testing.T) {
tree := NewWithIntComparator(3)
assertValidTree(t, tree, 0)
tree.Put(6, nil)
assertValidTree(t, tree, 1)
assertValidTreeNode(t, tree.Root, 1, 0, []int{6}, false)
tree.Put(5, nil)
assertValidTree(t, tree, 2)
assertValidTreeNode(t, tree.Root, 2, 0, []int{5, 6}, false)
tree.Put(4, nil)
assertValidTree(t, tree, 3)
assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{4}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true)
tree.Put(3, nil)
assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{3, 4}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true)
tree.Put(2, nil)
assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true)
assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true)
tree.Put(1, nil)
assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false)
assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{1, 2}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true)
assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true)
tree.Put(0, nil)
assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{0}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)
tree.Put(-1, nil)
assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)
assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true)
assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-1, 0}, true)
assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)
assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)
fmt.Println(tree)
//tree.Put(-2, nil)
//tree.Put(-3, nil)
//tree.Put(-4, nil)
//tree.Put(-5, nil)
//tree.Put(-6, nil)
//fmt.Println(tree)
}
func TestBTree_height(t *testing.T) {
func TestBTreeHeight(t *testing.T) {
tree := NewWithIntComparator(3)
if actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
@ -234,13 +319,58 @@ func TestBTree_height(t *testing.T) {
}
}
func TestBTree_search(t *testing.T) {
{
tree := NewWithIntComparator(3)
tree.Root = &Node{Entries: []*Entry{}, Children: make([]*Node, 0)}
tests := [][]interface{}{
{0, 0, false},
}
for _, test := range tests {
index, found := tree.search(tree.Root, test[0])
if actualValue, expectedValue := index, test[1]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := found, test[2]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
{
tree := NewWithIntComparator(3)
tree.Root = &Node{Entries: []*Entry{{2, 0}, {4, 1}, {6, 2}}, Children: []*Node{}}
tests := [][]interface{}{
{0, 0, false},
{1, 0, false},
{2, 0, true},
{3, 1, false},
{4, 1, true},
{5, 2, false},
{6, 2, true},
{7, 3, false},
}
for _, test := range tests {
index, found := tree.search(tree.Root, test[0])
if actualValue, expectedValue := index, test[1]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := found, test[2]; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
}
func assertValidTree(t *testing.T, tree *Tree, expectedSize int) {
if actualValue, expectedValue := tree.size, expectedSize; actualValue != expectedValue {
t.Errorf("Got %v expected %v for tree size", actualValue, expectedValue)
}
}
func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expectedChildren int, keys []int) {
func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expectedChildren int, keys []int, hasParent bool) {
if actualValue, expectedValue := node.Parent != nil, hasParent; actualValue != expectedValue {
t.Errorf("Got %v expected %v for hasParent", actualValue, expectedValue)
}
if actualValue, expectedValue := len(node.Entries), expectedEntries; actualValue != expectedValue {
t.Errorf("Got %v expected %v for entries size", actualValue, expectedValue)
}

Loading…
Cancel
Save