Skip to content

Commit

Permalink
delete unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
vision9527 committed Mar 16, 2022
1 parent ea75f23 commit ee4ea52
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 48 deletions.
59 changes: 39 additions & 20 deletions btree.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func (b *BPlusTree) CountNode() {
}
}

// 层序打印树结构
func (b *BPlusTree) Print() {
fmt.Println("----------------------------------------------------------------------------------------------------start print tree")
fmt.Printf("InternalMaxSize:%d LeafMaxSize: %d\n", b.internalMaxSize, b.leafMaxSize)
Expand Down Expand Up @@ -231,7 +232,7 @@ func print(prt bool, a ...interface{}) {
}
}

// 检查是否满足B+树(仅测试用)
// 检查是否满足B+树(仅测试用,并且有点小问题,不想改了)
func (b *BPlusTree) check(prt bool) {
defer func() {
if err := recover(); err != nil {
Expand All @@ -243,18 +244,24 @@ func (b *BPlusTree) check(prt bool) {
return
}
if b.root.isLeaf {
if len(b.root.keys) > b.leafMaxSize {
panic("b plus tree wrong max size")
}
for i, ky := range b.root.keys {
if i == 0 {
// fmt.Println("key: ", ky)
continue
}
if ky.compare(b.root.keys[i-1]) != 1 {
panic("b plus tree error")
panic(fmt.Sprintf("b plus tree error i=%d ky=%s", i, ky))
}
// fmt.Println("key: ", ky)
}
return
}
if len(b.root.keys) > b.internalMaxSize {
panic("b plus tree wrong max size")
}
for i, ky := range b.root.keys {
n := b.root.pointers[i].(*node)
if i == 0 {
Expand All @@ -266,7 +273,7 @@ func (b *BPlusTree) check(prt bool) {
b.checkTree(n, ky, prt)
print(prt, "key: ", ky)
} else {
panic("b plus tree error")
panic(fmt.Sprintf("b plus tree error i=%d ky=%s", i, ky))
}
}
b.checkTree(b.root.lastOrNextNode, "", prt)
Expand All @@ -276,6 +283,9 @@ func (b *BPlusTree) checkTree(nd *node, lastKey key, prt bool) {
if !nd.isHalf() {
panic(fmt.Sprintf("nd should be half but: %d", len(nd.keys)))
}
if len(nd.keys) > nd.maxSize {
panic("b plus tree node wrong max size")
}
if nd.isLeaf {
for i, ky := range nd.keys {
if lastKey.compare("") == 0 {
Expand Down Expand Up @@ -458,7 +468,6 @@ func (b *BPlusTree) insertIntoParent(oldNode, newNode *node, childKey key) {
parentNode.pointers = make([]interface{}, 0)
siblingParentNode := b.makeEmptyInternalNode()
parentNode.keys = append(parentNode.keys, tempKeys[0:parentNode.getHalf()]...)
// parentNode.pointers = append(parentNode.pointers, tempPointers[0:b.internalMaxSize/2]...)
for i := 0; i < parentNode.getHalf(); i++ {
childPointer := tempPointers[i]
parentNode.pointers = append(parentNode.pointers, childPointer)
Expand Down Expand Up @@ -488,7 +497,6 @@ func (b *BPlusTree) insertIntoParent(oldNode, newNode *node, childKey key) {
}

siblingParentNode.keys = append(siblingParentNode.keys, tempKeys[parentNode.getHalf()+1:]...)
// siblingParentNode.pointers = append(siblingParentNode.pointers, tempPointers[b.internalMaxSize/2+1:b.internalMaxSize+1]...)
for i := parentNode.getHalf() + 1; i < parentNode.maxSize+1; i++ {
childPointer := tempPointers[i]
siblingParentNode.pointers = append(siblingParentNode.pointers, childPointer)
Expand Down Expand Up @@ -537,7 +545,6 @@ func (b *BPlusTree) delete(ky key) (interface{}, bool) {
return v.value, true
}
func (b *BPlusTree) deleteNode(nd *node, ky key, p interface{}) {
fmt.Println("deleteNode: ", nd, ky, p)
nd.delete(ky, p)
if nd.parent == nil && len(nd.keys) == 0 {
b.root = nd.lastOrNextNode
Expand All @@ -549,49 +556,51 @@ func (b *BPlusTree) deleteNode(nd *node, ky key, p interface{}) {
if nd.parent == nil {
return
}
fmt.Println("ndndnd: ", nd)
if !nd.isHalf() {
sibling, index, ky, isPrev := nd.lookupSibling()
// if sibling == nil {
// return
// }
fmt.Printf("ndndnd:%v sibling:%v index:%d ky:%s isPrev:%v\n", nd, sibling, index, ky, isPrev)
if len(sibling.keys)+len(nd.keys) <= nd.maxSize {
if len(sibling.keys)+len(nd.keys) < nd.maxSize {
// Coalesce
if !isPrev {
sibling, nd = nd, sibling
}
fmt.Printf("ndndnd:%v sibling:%v parent:%v\n", nd, sibling, sibling.parent)
if !sibling.isLeaf {
sibling.keys = append(sibling.keys, ky)
sibling.keys = append(sibling.keys, nd.keys...)
sibling.pointers = append(sibling.pointers, sibling.lastOrNextNode)
sibling.pointers = append(sibling.pointers, nd.pointers...)
sibling.lastOrNextNode = nd.lastOrNextNode
for _, p := range sibling.pointers {
p.(*node).parent = sibling
}
if sibling.lastOrNextNode != nil {
sibling.lastOrNextNode.parent = sibling
}
} else {
sibling.keys = append(sibling.keys, nd.keys...)
sibling.pointers = append(sibling.pointers, nd.pointers...)
sibling.lastOrNextNode = nd.lastOrNextNode
}
b.deleteNode(sibling.parent, ky, nd)
} else {
fmt.Println("Redistribution")
// Redistribution
if isPrev {
var lastKey key
if !nd.isLeaf {
lastKey := sibling.keys[len(sibling.keys)-1]
lastKey = sibling.keys[len(sibling.keys)-1]
lastPointer := sibling.lastOrNextNode
tempKeys := []key{lastKey}
tempKeys := []key{ky}
tempPointers := []interface{}{lastPointer}
tempKeys = append(tempKeys, nd.keys...)
tempPointers = append(tempPointers, nd.pointers...)
nd.keys = tempKeys
nd.pointers = tempPointers
lastPointer.parent = nd
sibling.keys = sibling.keys[0 : len(sibling.keys)-1]
sibling.lastOrNextNode = sibling.pointers[len(sibling.pointers)-1].(*node)
sibling.pointers = sibling.pointers[0 : len(sibling.pointers)-1]
nd.parent.keys[index] = lastKey
} else {
lastKey := sibling.keys[len(sibling.keys)-1]
lastKey = sibling.keys[len(sibling.keys)-1]
lastPointer := sibling.pointers[len(sibling.pointers)-1]
tempKeys := []key{lastKey}
tempPointers := []interface{}{lastPointer}
Expand All @@ -604,15 +613,25 @@ func (b *BPlusTree) deleteNode(nd *node, ky key, p interface{}) {
nd.parent.keys[index] = lastKey
}
} else {
var firstKey key
if !nd.isLeaf {
firstKey := sibling.keys[0]
firstKey = sibling.keys[0]
firstPointer := sibling.pointers[0]
nd.keys = append(nd.keys, firstKey)
nd.keys = append(nd.keys, ky)
nd.pointers = append(nd.pointers, nd.lastOrNextNode)
nd.lastOrNextNode = firstPointer.(*node)
firstPointer.(*node).parent = nd
sibling.keys = sibling.keys[1:]
sibling.pointers = sibling.pointers[1:]
nd.parent.keys[index] = firstKey
} else {
firstKey = sibling.keys[0]
firstPointer := sibling.pointers[0]
nd.keys = append(nd.keys, firstKey)
nd.pointers = append(nd.pointers, firstPointer)
sibling.keys = sibling.keys[1:]
sibling.pointers = sibling.pointers[1:]
nd.parent.keys[index] = ky
nd.parent.keys[index] = sibling.keys[0]
}
}
}
Expand Down
54 changes: 40 additions & 14 deletions btree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ func TestBPlusTreeFind_rootHaveChild(t *testing.T) {
[]string{"El Said_value", "Gold_value", "Katz_value", "Kim_value"})
nodeThree := makeTestLeafNode([]string{"Mozart", "Singh", "Srinivasan", "Wu"},
[]string{"Mozart_value", "Singh_value", "Srinivasan_value", "Wu_value"})
nodeOne.maxSize = 6
nodeTwo.maxSize = 6
nodeThree.maxSize = 6
tree.root.pointers[0] = nodeOne
tree.root.pointers[1] = nodeTwo
tree.root.lastOrNextNode = nodeThree
Expand Down Expand Up @@ -180,6 +183,7 @@ func TestBPlusTree_insertIntoLeaf(t *testing.T) {
tree, _ := StartNewTree(6, 6)
leafNode := makeTestLeafNode([]string{"key1", "key2", "key4", "key5"},
[]string{"key1_value", "key2_value", "key4_value", "key5_value"})
leafNode.maxSize = 6
targetKey := key("key3")
et := &entry{
value: "key3_value",
Expand Down Expand Up @@ -719,30 +723,29 @@ func TestBPlusTree_DeleteOne(t *testing.T) {
}

func TestBPlusTree_DeleteTwo(t *testing.T) {
t.Skip()
tree, _ := StartNewTree(3, 3)
testkv := GenTestKeyAndValue(3)
for i := 0; i < len(testkv); i++ {
tree.Insert(testkv[i], testkv[i])
tree.check(false)
}
tree.Print()
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
v, ok := tree.Delete(ky)
tree.check(false)
if !ok {
t.Fatalf("value should exsit")
}
if toString(v) != value {
t.Fatalf("value should be %s, but value:%v", ky, v)
}
}
tree.check(false)

}

func TestBPlusTree_DeleteThree(t *testing.T) {
t.Skip()
num := 100
for n := 4; n < num; n++ {
tree, _ := StartNewTree(n+10, n)
Expand All @@ -753,6 +756,7 @@ func TestBPlusTree_DeleteThree(t *testing.T) {
value := testkv[i]
tree.Insert(ky, value)
v, ok := tree.Delete(ky)
tree.check(false)
if !ok {
t.Fatalf("value should exsit")
}
Expand All @@ -764,20 +768,17 @@ func TestBPlusTree_DeleteThree(t *testing.T) {
}

func TestBPlusTree_DeleteFour(t *testing.T) {
t.Skip()
tree, _ := StartNewTree(4, 4)
testkv := GenTestKeyAndValue(3)
// ShuffleTestkv(testkv)
// fmt.P
testkv := GenTestKeyAndValue(4)
ShuffleTestkv(testkv)
for i := 0; i < len(testkv); i++ {
tree.Insert(testkv[i], testkv[i])
}
tree.Print()
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
tree.Print()
fmt.Println("ky: ", ky)
// tree.Print()
v, ok := tree.Delete(ky)
tree.check(false)
if !ok {
Expand All @@ -788,15 +789,40 @@ func TestBPlusTree_DeleteFour(t *testing.T) {
}
}

num := 100
for n := 4; n < num; n++ {
tree, _ := StartNewTree(4, 4)
testkv := GenTestKeyAndValue(n)
ShuffleTestkv(testkv)
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
tree.Insert(ky, value)
}
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
// tree.Print()
v, ok := tree.Delete(ky)
tree.check(false)
if !ok {
tree.Print()
t.Fatalf("value should exsit")
}
if toString(v) != value {
t.Fatalf("value should be %s, but value:%v", ky, v)
}
}
}

}

func TestBPlusTree_DeleteFive(t *testing.T) {
t.Skip()
num := 100
for n := 4; n < num; n++ {
tree, _ := StartNewTree(n+10, n)
tree, _ := StartNewTree(n, n)
testkv := GenTestKeyAndValue(n)
// ShuffleTestkv(testkv)
ShuffleTestkv(testkv)
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
Expand All @@ -806,9 +832,9 @@ func TestBPlusTree_DeleteFive(t *testing.T) {
for i := 0; i < len(testkv); i++ {
ky := testkv[i]
value := testkv[i]
tree.Print()
// tree.Print()
v, ok := tree.Delete(ky)
fmt.Println("ky: ", ky)
tree.check(false)
if !ok {
tree.Print()
t.Fatalf("value should exsit")
Expand Down
15 changes: 1 addition & 14 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type node struct {
// 是否是叶子节点
isLeaf bool
keys []key
// 非叶子节点是*Node,叶子节点是*entry, 最后一个指针挪到了lastOrNextNode
// 非叶子节点是*node,叶子节点是*entry, 最后一个指针挪到了lastOrNextNode
// 所以len(keys)=len(pointers)
pointers []interface{}
parent *node
Expand Down Expand Up @@ -35,7 +35,6 @@ func (n *node) delete(targetKey key, p interface{}) {
break
}
}
fmt.Println("delete index: ", index)
tempKeys := n.keys[0:index]
if index < len(n.keys)-1 {
tempKeys = append(tempKeys, n.keys[index+1:]...)
Expand Down Expand Up @@ -131,9 +130,6 @@ func (nd *node) lookupSibling() (sibling *node, index int, ky key, isPrev bool)
}
}
if index == -1 {
fmt.Println("Aindex: ", index, len(nd.parent.pointers))
fmt.Println("node: ", nd)
fmt.Println("node parent: ", nd.parent)
index = len(nd.parent.pointers) - 1
sibling = nd.parent.pointers[index].(*node)
isPrev = true
Expand All @@ -142,28 +138,19 @@ func (nd *node) lookupSibling() (sibling *node, index int, ky key, isPrev bool)
}
// pointers里最后一个
if index == len(nd.parent.pointers)-1 {
fmt.Println("Bindex: ", index, len(nd.parent.pointers))
fmt.Println("node: ", nd)
fmt.Println("node parent: ", nd.parent)
sibling = nd.parent.lastOrNextNode
isPrev = false
ky = nd.parent.keys[index]
return
} else if index == 0 {
// pointers里第一个
fmt.Println("Cindex: ", index, len(nd.parent.pointers))
fmt.Println("node: ", nd)
fmt.Println("node parent: ", nd.parent)
// index = index + 1
sibling = nd.parent.pointers[index+1].(*node)
isPrev = false
ky = nd.parent.keys[0]
return
} else {
// 默认用前一个
fmt.Println("Dindex: ", index, len(nd.parent.pointers))
fmt.Println("node: ", nd)
fmt.Println("node parent: ", nd.parent)
index = index - 1
ky = nd.parent.keys[index]
sibling = nd.parent.pointers[index].(*node)
Expand Down

0 comments on commit ee4ea52

Please sign in to comment.