package main
import "fmt"
type BPlustree map[int]node //定义
func NewBplusTree() *BPlustree {
bt := BPlustree{} //初始化
leaf := NewLeafNode(nil) //叶子节点
r := NewinteriorNode(nil, leaf) //中间节点
leaf.parent = r //设定父亲节点
bt[-1] = r //根节点
bt[0] = leaf
return &bt
}
//返回根节点
func (bpt *BPlustree) Root() node {
return (*bpt)[-1]
}
//处理第一个节点
func (bpt *BPlustree) First() node {
return (*bpt)[0]
}
//统计数量
func (bpt *BPlustree) Count() int {
count := 0
leaf := (*bpt)[0].(*LeafNode)
for {
count += leaf.CountNum() //数量叠加
if leaf.next == nil {
break
}
leaf = leaf.next
}
return count
}
func (bpt *BPlustree) Values() []*LeafNode {
nodes := make([]*LeafNode, 0) //开辟节点
leaf := (*bpt)[0].(*LeafNode)
for {
nodes = append(nodes, leaf) //数据节点叠加
if leaf.next == nil {
break
}
leaf = leaf.next
}
return nodes
}
//查找数据
func (bpt *BPlustree) Search(key int) (string, bool) {
kv, _, _ := search((*bpt)[-1], key) //查找
if kv == nil {
return "", false
} else {
return kv.value, true
}
}
//搜索数据
func search(n node, key int) (*kv, int, *LeafNode) {
curr := n
oldindex := -1
for {
switch t := curr.(type) {
case *LeafNode: //叶子节点搜索
i, ok := t.find(key)
if !ok {
return nil, oldindex, t
} else {
return &t.kvs[i], oldindex, t
}
case *interiorNode:
i, _ := t.find(key) //中间节点查找
curr = t.kcs[i].child
oldindex = i
default:
panic("异常节点")
}
}
}
// 1 6
//12345 6789
func (bpt *BPlustree) Insert(key int, value string) {
//插入之前,确定插入的位置
_, oldindex, leaf := search((*bpt)[-1], key)
p := leaf.Parent() //保存父亲节点
//插入叶子节点,判断是否分裂
mid, nextleaf, bump := leaf.insert(key, value)
if !bump { //没有分裂,直接返回
return
}
//f分裂的节点插入B+树
(*bpt)[mid] = nextleaf
//中间节点
var midnode node
midnode = leaf
p.kcs[oldindex].child = leaf.next //设置父亲节点
leaf.next.SetParent(p) //分裂的节点设置父亲节点
interior, interiorP := p, p.Parent() //获取中间点解,父亲节点
//平衡过程,迭代向上判断,是否需要平衡
for {
var oldindex int //保存老的索引
var newinterior *interiorNode //新的节点
//判断是否到达根节点
isRoot := interiorP == nil
if !isRoot {
oldindex, _ = interiorP.find(key) //查找
}
//叶子节点分裂后的中间节点传入父亲的中间节点,传入分裂
mid, newinterior, bump = interior.insert(mid, midnode)
if !bump {
return
}
(*bpt)[newinterior.kcs[0].key] = newinterior //插入填充好了map
if !isRoot {
interiorP.kcs[oldindex].child = newinterior //没有到大根节点,直接插入父亲节点
newinterior.SetParent(interiorP)
midnode = interior
} else {
//更新节点
(*bpt)[interior.kcs[0].key] = (*bpt)[-1] //备份根节点
(*bpt)[-1] = NewinteriorNode(nil, newinterior) //根节点插入新的根节点
node := (*bpt)[-1].(*interiorNode)
node.insert(mid, interior) //重新插入
(*bpt)[-1] = node
newinterior.SetParent(node) //设定父亲节点
}
interior, interiorP = interiorP, interior.Parent()
}
}
func main() {
bpt := NewBplusTree()
for i := 0; i < 250000; i++ {
bpt.Insert(i, "x")
}
fmt.Println(bpt.Count())
fmt.Println(bpt.Search(3))
}