494 lines
9.9 KiB
Go
494 lines
9.9 KiB
Go
package lsv
|
|
|
|
// INode 用于索引的节点
|
|
type INode struct {
|
|
family [3]*INode
|
|
size int
|
|
tree *DTree
|
|
}
|
|
|
|
// NewINode 生成inode节点
|
|
func NewINode() *INode {
|
|
inode := &INode{}
|
|
inode.size = 1
|
|
inode.tree = newDataTree(compareRunes)
|
|
return inode
|
|
}
|
|
|
|
// ITree 用于索引的树
|
|
type ITree struct {
|
|
root *INode
|
|
limit int
|
|
Compare func(s1, s2 []rune) int
|
|
}
|
|
|
|
// New 生成一颗索引树
|
|
func New(Compare func(s1, s2 []rune) int) *ITree {
|
|
return &ITree{Compare: Compare, limit: 100}
|
|
}
|
|
|
|
// Put return bool
|
|
func (tree *ITree) Put(key, value []rune) (isInsert bool) {
|
|
|
|
// node := &INode{key: key, value: value, size: 1}
|
|
if tree.root == nil {
|
|
|
|
tree.root = NewINode()
|
|
return tree.root.tree.Put(key, value)
|
|
|
|
}
|
|
|
|
for cur := tree.root; ; {
|
|
|
|
if cur.size > 8 {
|
|
factor := cur.size / 10 // or factor = 1
|
|
ls, rs := cur.family[1].size, cur.family[2].size
|
|
if rs >= ls*2+factor || ls >= rs*2+factor {
|
|
tree.ifixSize(cur, ls, rs)
|
|
}
|
|
}
|
|
|
|
c := tree.Compare(key, cur.tree.feature.key)
|
|
switch {
|
|
case c < 0:
|
|
if cur.family[1] == nil {
|
|
|
|
if cur.tree.root.size >= tree.limit {
|
|
// 子树的节点分解 操作
|
|
lspilt := cur.tree.root.family[1]
|
|
rspilt := cur.tree.root.family[2]
|
|
|
|
// 根树 新节点要插入到 右节点的最小值位置 即是 左~
|
|
irnode := NewINode()
|
|
irnode.tree.root = rspilt
|
|
irnode.tree.feature = cur.tree.feature
|
|
|
|
icur := cur.family[2]
|
|
if icur == nil {
|
|
cur.family[2] = irnode
|
|
} else {
|
|
for ; icur.family[1] != nil; icur = icur.family[1] {
|
|
}
|
|
|
|
icur.family[1] = irnode
|
|
irnode.family[0] = icur
|
|
|
|
for temp := icur; temp != nil; temp = temp.family[0] {
|
|
temp.size++
|
|
}
|
|
|
|
// 调整3节点失衡的情况
|
|
if cur.family[0] != nil && cur.family[0].size == 3 {
|
|
if cur.family[0].family[1] == nil {
|
|
tree.ilrrotate3(cur.family[0])
|
|
} else {
|
|
tree.irrotate3(cur.family[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
rspilt.family[0] = nil
|
|
|
|
tempRoot := cur.tree.root
|
|
|
|
lspilt.family[0] = nil
|
|
cur.tree.root = lspilt
|
|
|
|
tempRoot.size = 1
|
|
for i := 1; i < len(tempRoot.family); i++ {
|
|
tempRoot.family[i] = nil
|
|
}
|
|
|
|
cur.tree.putfeature(tempRoot)
|
|
}
|
|
|
|
return cur.tree.Put(key, value)
|
|
|
|
// inode := NewINode()
|
|
// cur.family[1] = inode
|
|
// inode.family[0] = cur
|
|
|
|
// for temp := cur; temp != nil; temp = temp.family[0] {
|
|
// temp.size++
|
|
// }
|
|
|
|
// if cur.family[0] != nil && cur.family[0].size == 3 {
|
|
// if cur.family[0].family[1] == nil {
|
|
// tree.ilrrotate3(cur.family[0])
|
|
// } else {
|
|
// tree.irrotate3(cur.family[0])
|
|
// }
|
|
// }
|
|
// return true
|
|
}
|
|
cur = cur.family[1]
|
|
case c > 0:
|
|
if cur.family[2] == nil {
|
|
|
|
if cur.tree.root.size >= tree.limit {
|
|
lspilt := cur.tree.root.family[1]
|
|
rspilt := cur.tree.root.family[2]
|
|
// cur.family
|
|
irnode := NewINode()
|
|
irnode.tree.root = rspilt
|
|
icur := cur.family[2]
|
|
if icur == nil {
|
|
cur.family[2] = irnode
|
|
} else {
|
|
for ; icur.family[1] != nil; icur = icur.family[1] {
|
|
}
|
|
|
|
icur.family[1] = irnode
|
|
irnode.family[0] = icur
|
|
|
|
for temp := icur; temp != nil; temp = temp.family[0] {
|
|
temp.size++
|
|
}
|
|
|
|
// 调整3节点失衡的情况
|
|
if icur.family[0] != nil && icur.family[0].size == 3 {
|
|
if icur.family[0].family[2] == nil {
|
|
tree.irlrotate3(icur.family[0])
|
|
} else {
|
|
tree.ilrotate3(icur.family[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
rspilt.family[0] = nil
|
|
|
|
// cur.family irnode
|
|
|
|
tempRoot := cur.tree.root
|
|
|
|
lspilt.family[0] = nil
|
|
cur.tree.root = lspilt
|
|
|
|
tempRoot.size = 1
|
|
for i := 1; i < len(tempRoot.family); i++ {
|
|
tempRoot.family[i] = nil
|
|
}
|
|
|
|
cur.tree.putfeature(tempRoot)
|
|
}
|
|
|
|
return cur.tree.Put(key, value)
|
|
|
|
// inode := NewINode()
|
|
// cur.family[2] = inode
|
|
// inode.family[0] = cur
|
|
|
|
// for temp := cur; temp != nil; temp = temp.family[0] {
|
|
// temp.size++
|
|
// }
|
|
|
|
// if cur.family[0] != nil && cur.family[0].size == 3 {
|
|
// if cur.family[0].family[2] == nil {
|
|
// tree.irlrotate3(cur.family[0])
|
|
// } else {
|
|
// tree.ilrotate3(cur.family[0])
|
|
// }
|
|
// }
|
|
// return true
|
|
}
|
|
cur = cur.family[2]
|
|
default:
|
|
return cur.tree.Put(key, value)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func (tree *ITree) String() {
|
|
|
|
}
|
|
|
|
func (tree *ITree) ifixSize(cur *INode, ls, rs int) {
|
|
if ls > rs {
|
|
llsize, lrsize := igetChildrenSize(cur.family[1])
|
|
if lrsize > llsize {
|
|
tree.irlrotate(cur)
|
|
} else {
|
|
tree.irrotate(cur)
|
|
}
|
|
} else {
|
|
rlsize, rrsize := igetChildrenSize(cur.family[2])
|
|
if rlsize > rrsize {
|
|
tree.ilrrotate(cur)
|
|
} else {
|
|
tree.ilrotate(cur)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (tree *ITree) ilrrotate3(cur *INode) {
|
|
const l = 2
|
|
const r = 1
|
|
|
|
movparent := cur.family[l]
|
|
mov := movparent.family[r]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
cur.family[l] = movparent
|
|
movparent.family[r] = nil
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
cur.family[l].size = 1
|
|
}
|
|
|
|
func (tree *ITree) ilrrotate(cur *INode) {
|
|
|
|
const l = 2
|
|
const r = 1
|
|
|
|
movparent := cur.family[l]
|
|
mov := movparent.family[r]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
if mov.family[l] != nil {
|
|
movparent.family[r] = mov.family[l]
|
|
movparent.family[r].family[0] = movparent
|
|
//movparent.family[r].child = l
|
|
} else {
|
|
movparent.family[r] = nil
|
|
}
|
|
|
|
if mov.family[r] != nil {
|
|
mov.family[l] = mov.family[r]
|
|
//mov.family[l].child = l
|
|
} else {
|
|
mov.family[l] = nil
|
|
}
|
|
|
|
if cur.family[r] != nil {
|
|
mov.family[r] = cur.family[r]
|
|
mov.family[r].family[0] = mov
|
|
} else {
|
|
mov.family[r] = nil
|
|
}
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
movparent.size = igetChildrenSumSize(movparent) + 1
|
|
mov.size = igetChildrenSumSize(mov) + 1
|
|
cur.size = igetChildrenSumSize(cur) + 1
|
|
}
|
|
|
|
func (tree *ITree) irlrotate3(cur *INode) {
|
|
const l = 1
|
|
const r = 2
|
|
|
|
movparent := cur.family[l]
|
|
mov := movparent.family[r]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
cur.family[l] = movparent
|
|
movparent.family[r] = nil
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
// cur.size = 3
|
|
// cur.family[r].size = 1
|
|
cur.family[l].size = 1
|
|
}
|
|
|
|
func (tree *ITree) irlrotate(cur *INode) {
|
|
|
|
const l = 1
|
|
const r = 2
|
|
|
|
movparent := cur.family[l]
|
|
mov := movparent.family[r]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
if mov.family[l] != nil {
|
|
movparent.family[r] = mov.family[l]
|
|
movparent.family[r].family[0] = movparent
|
|
} else {
|
|
movparent.family[r] = nil
|
|
}
|
|
|
|
if mov.family[r] != nil {
|
|
mov.family[l] = mov.family[r]
|
|
} else {
|
|
mov.family[l] = nil
|
|
}
|
|
|
|
if cur.family[r] != nil {
|
|
mov.family[r] = cur.family[r]
|
|
mov.family[r].family[0] = mov
|
|
} else {
|
|
mov.family[r] = nil
|
|
}
|
|
|
|
cur.family[r] = mov
|
|
mov.family[0] = cur
|
|
|
|
movparent.size = igetChildrenSumSize(movparent) + 1
|
|
mov.size = igetChildrenSumSize(mov) + 1
|
|
cur.size = igetChildrenSumSize(cur) + 1
|
|
}
|
|
|
|
func (tree *ITree) irrotate3(cur *INode) {
|
|
const l = 1
|
|
const r = 2
|
|
// 1 right 0 left
|
|
mov := cur.family[l]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
cur.family[r] = mov
|
|
|
|
cur.family[l] = mov.family[l]
|
|
cur.family[l].family[0] = cur
|
|
|
|
mov.family[l] = nil
|
|
|
|
mov.size = 1
|
|
}
|
|
|
|
func (tree *ITree) irrotate(cur *INode) {
|
|
|
|
const l = 1
|
|
const r = 2
|
|
// 1 right 0 left
|
|
mov := cur.family[l]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
// mov.family[l]不可能为nil
|
|
mov.family[l].family[0] = cur
|
|
|
|
cur.family[l] = mov.family[l]
|
|
|
|
// 解决mov节点孩子转移的问题
|
|
if mov.family[r] != nil {
|
|
mov.family[l] = mov.family[r]
|
|
} else {
|
|
mov.family[l] = nil
|
|
}
|
|
|
|
if cur.family[r] != nil {
|
|
mov.family[r] = cur.family[r]
|
|
mov.family[r].family[0] = mov
|
|
} else {
|
|
mov.family[r] = nil
|
|
}
|
|
|
|
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
|
|
cur.family[r] = mov
|
|
|
|
mov.size = igetChildrenSumSize(mov) + 1
|
|
cur.size = igetChildrenSumSize(cur) + 1
|
|
}
|
|
|
|
func (tree *ITree) ilrotate3(cur *INode) {
|
|
const l = 2
|
|
const r = 1
|
|
// 1 right 0 left
|
|
mov := cur.family[l]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
cur.family[r] = mov
|
|
|
|
cur.family[l] = mov.family[l]
|
|
cur.family[l].family[0] = cur
|
|
|
|
mov.family[l] = nil
|
|
|
|
mov.size = 1
|
|
}
|
|
|
|
func (tree *ITree) ilrotate(cur *INode) {
|
|
|
|
const l = 2
|
|
const r = 1
|
|
// 1 right 0 left
|
|
mov := cur.family[l]
|
|
|
|
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
|
|
|
|
// mov.family[l]不可能为nil
|
|
mov.family[l].family[0] = cur
|
|
|
|
cur.family[l] = mov.family[l]
|
|
|
|
// 解决mov节点孩子转移的问题
|
|
if mov.family[r] != nil {
|
|
mov.family[l] = mov.family[r]
|
|
} else {
|
|
mov.family[l] = nil
|
|
}
|
|
|
|
if cur.family[r] != nil {
|
|
mov.family[r] = cur.family[r]
|
|
mov.family[r].family[0] = mov
|
|
} else {
|
|
mov.family[r] = nil
|
|
}
|
|
|
|
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
|
|
cur.family[r] = mov
|
|
|
|
mov.size = igetChildrenSumSize(mov) + 1
|
|
cur.size = igetChildrenSumSize(cur) + 1
|
|
}
|
|
|
|
func igetChildrenSumSize(cur *INode) int {
|
|
return igetSize(cur.family[1]) + igetSize(cur.family[2])
|
|
}
|
|
|
|
func igetChildrenSize(cur *INode) (int, int) {
|
|
return igetSize(cur.family[1]), igetSize(cur.family[2])
|
|
}
|
|
|
|
func igetSize(cur *INode) int {
|
|
if cur == nil {
|
|
return 0
|
|
}
|
|
return cur.size
|
|
}
|
|
|
|
func (tree *ITree) ifixSizeWithRemove(cur *INode) {
|
|
for cur != nil {
|
|
cur.size--
|
|
if cur.size > 8 {
|
|
factor := cur.size / 10 // or factor = 1
|
|
ls, rs := igetChildrenSize(cur)
|
|
if rs >= ls*2+factor || ls >= rs*2+factor {
|
|
tree.ifixSize(cur, ls, rs)
|
|
}
|
|
} else if cur.size == 3 {
|
|
if cur.family[1] == nil {
|
|
if cur.family[2].family[1] == nil {
|
|
tree.ilrotate3(cur)
|
|
} else {
|
|
tree.ilrrotate3(cur)
|
|
}
|
|
} else if cur.family[2] == nil {
|
|
if cur.family[1].family[2] == nil {
|
|
tree.irrotate3(cur)
|
|
} else {
|
|
tree.irlrotate3(cur)
|
|
}
|
|
}
|
|
}
|
|
cur = cur.family[0]
|
|
}
|
|
}
|