rbt: avoid sharing rbtree neel pointer

This commit is contained in:
c9s 2021-06-06 17:09:22 +08:00
parent f487b53d9e
commit 7512f56b84

View File

@ -6,22 +6,23 @@ import (
"github.com/c9s/bbgo/pkg/fixedpoint"
)
var Neel = &RBNode{
Color: Black,
}
type RBTree struct {
Root *RBNode
neel *RBNode
size int
}
func NewRBTree() *RBTree {
var root = Neel
root.Parent = Neel
var neel = &RBNode{
Color: Black,
}
var root = neel
root.Parent = neel
return &RBTree{
Root: root,
neel: neel,
}
}
@ -35,17 +36,13 @@ func (tree *RBTree) Delete(key fixedpoint.Value) bool {
// x (the child of the deleted node)
var x, y *RBNode
if del.Left == Neel || del.Right == Neel {
if del.Left == tree.neel || del.Right == tree.neel {
y = del
} else {
y = tree.Successor(del)
if y == nil {
// prevent segmentation fault
y = Neel
}
}
if y.Left != Neel {
if y.Left != tree.neel {
x = y.Left
} else {
x = y.Right
@ -53,7 +50,7 @@ func (tree *RBTree) Delete(key fixedpoint.Value) bool {
x.Parent = y.Parent
if y.Parent == Neel {
if y.Parent == tree.neel {
tree.Root = x
} else if y == y.Parent.Left {
y.Parent.Left = x
@ -139,7 +136,7 @@ func (tree *RBTree) DeleteFixup(current *RBNode) {
}
func (tree *RBTree) Upsert(key, val fixedpoint.Value) {
var y = Neel
var y = tree.neel
var x = tree.Root
var node = &RBNode{
Key: key,
@ -147,7 +144,7 @@ func (tree *RBTree) Upsert(key, val fixedpoint.Value) {
Color: Red,
}
for x != Neel {
for x != tree.neel {
y = x
if node.Key == x.Key {
@ -163,7 +160,7 @@ func (tree *RBTree) Upsert(key, val fixedpoint.Value) {
node.Parent = y
if y == Neel {
if y == tree.neel {
tree.Root = node
} else if node.Key < y.Key {
y.Left = node
@ -171,23 +168,25 @@ func (tree *RBTree) Upsert(key, val fixedpoint.Value) {
y.Right = node
}
node.Left = Neel
node.Right = Neel
node.Left = tree.neel
node.Right = tree.neel
node.Color = Red
tree.InsertFixup(node)
}
func (tree *RBTree) Insert(key, val fixedpoint.Value) {
var y = Neel
var y = tree.neel
var x = tree.Root
var node = &RBNode{
Key: key,
Value: val,
Color: Red,
Left: tree.neel,
Right: tree.neel,
}
for x != Neel {
for x != tree.neel {
y = x
if node.Key < x.Key {
@ -199,7 +198,7 @@ func (tree *RBTree) Insert(key, val fixedpoint.Value) {
node.Parent = y
if y == Neel {
if y == tree.neel {
tree.Root = node
} else if node.Key < y.Key {
y.Left = node
@ -207,8 +206,8 @@ func (tree *RBTree) Insert(key, val fixedpoint.Value) {
y.Right = node
}
node.Left = Neel
node.Right = Neel
node.Left = tree.neel
node.Right = tree.neel
node.Color = Red
tree.size++
@ -217,7 +216,7 @@ func (tree *RBTree) Insert(key, val fixedpoint.Value) {
func (tree *RBTree) Search(key fixedpoint.Value) *RBNode {
var current = tree.Root
for current != Neel && key != current.Key {
for current != tree.neel && key != current.Key {
if key < current.Key {
current = current.Left
} else {
@ -226,7 +225,7 @@ func (tree *RBTree) Search(key fixedpoint.Value) *RBNode {
}
// convert Neel to real nil
if current == Neel {
if current == tree.neel {
return nil
}
@ -291,13 +290,13 @@ func (tree *RBTree) RotateLeft(x *RBNode) {
var y = x.Right
x.Right = y.Left
if y.Left != Neel {
if y.Left != tree.neel {
y.Left.Parent = x
}
y.Parent = x.Parent
if x.Parent == Neel {
if x.Parent == tree.neel {
tree.Root = y
} else if x == x.Parent.Left {
x.Parent.Left = y
@ -313,13 +312,13 @@ func (tree *RBTree) RotateRight(y *RBNode) {
x := y.Left
y.Left = x.Right
if x.Right != Neel {
if x.Right != tree.neel {
x.Right.Parent = y
}
x.Parent = y.Parent
if y.Parent == Neel {
if y.Parent == tree.neel {
tree.Root = x
} else if y == y.Parent.Left {
y.Parent.Left = x
@ -336,11 +335,7 @@ func (tree *RBTree) Rightmost() *RBNode {
}
func (tree *RBTree) RightmostOf(current *RBNode) *RBNode {
if current == Neel {
return nil
}
for current.Right != Neel {
for current.Right != nil {
current = current.Right
}
@ -352,11 +347,7 @@ func (tree *RBTree) Leftmost() *RBNode {
}
func (tree *RBTree) LeftmostOf(current *RBNode) *RBNode {
if current == Neel {
return nil
}
for current.Left != Neel {
for current.Left != nil {
current = current.Left
}
@ -364,24 +355,16 @@ func (tree *RBTree) LeftmostOf(current *RBNode) *RBNode {
}
func (tree *RBTree) Successor(current *RBNode) *RBNode {
if current == Neel {
return nil
}
if current.Right != Neel {
if current.Right != nil {
return tree.LeftmostOf(current.Right)
}
var newNode = current.Parent
for newNode != Neel && current == newNode.Right {
for newNode != nil && current == newNode.Right {
current = newNode
newNode = newNode.Parent
}
if newNode == Neel {
return nil
}
return newNode
}
@ -390,7 +373,7 @@ func (tree *RBTree) Preorder(cb func(n *RBNode)) {
}
func (tree *RBTree) PreorderOf(current *RBNode, cb func(n *RBNode)) {
if current != Neel {
if current != tree.neel {
cb(current)
tree.PreorderOf(current.Left, cb)
tree.PreorderOf(current.Right, cb)
@ -403,7 +386,7 @@ func (tree *RBTree) Inorder(cb func(n *RBNode) bool) {
}
func (tree *RBTree) InorderOf(current *RBNode, cb func(n *RBNode) bool) {
if current != Neel {
if current != tree.neel {
tree.InorderOf(current.Left, cb)
if !cb(current) {
return
@ -418,7 +401,7 @@ func (tree *RBTree) InorderReverse(cb func(n *RBNode) bool) {
}
func (tree *RBTree) InorderReverseOf(current *RBNode, cb func(n *RBNode) bool) {
if current != Neel {
if current != tree.neel {
tree.InorderReverseOf(current.Right, cb)
if !cb(current) {
return
@ -432,7 +415,7 @@ func (tree *RBTree) Postorder(cb func(n *RBNode) bool) {
}
func (tree *RBTree) PostorderOf(current *RBNode, cb func(n *RBNode) bool) {
if current != Neel {
if current != tree.neel {
tree.PostorderOf(current.Left, cb)
tree.PostorderOf(current.Right, cb)
if !cb(current) {
@ -441,14 +424,14 @@ func (tree *RBTree) PostorderOf(current *RBNode, cb func(n *RBNode) bool) {
}
}
func copyNode(node *RBNode) *RBNode {
if node == Neel {
return Neel
func (tree *RBTree) copyNode(node *RBNode) *RBNode {
if node == tree.neel {
return tree.neel
}
newNode := *node
newNode.Left = copyNode(node.Left)
newNode.Right = copyNode(node.Right)
newNode.Left = tree.copyNode(node.Left)
newNode.Right = tree.copyNode(node.Right)
return &newNode
}
@ -492,6 +475,6 @@ func (tree *RBTree) Print() {
func (tree *RBTree) Copy() *RBTree {
newTree := NewRBTree()
newTree.Root = copyNode(tree.Root)
newTree.Root = tree.copyNode(tree.Root)
return newTree
}