Skip to content

Commit

Permalink
fix rbtree insertion and rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
c9s committed May 22, 2021
1 parent 9b9643e commit 1531f2b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
6 changes: 4 additions & 2 deletions pkg/types/rbtorderbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@ func NewRBOrderBook(symbol string) *RBTOrderBook {
}

func (b *RBTOrderBook) BestBid() (PriceVolume, bool) {
right := b.Bids.Rightmost(b.Bids.Root)
right := b.Bids.Rightmost()
if right != nil {
return PriceVolume{Price: right.Key, Volume: right.Value}, true
}

return PriceVolume{}, false
}

func (b *RBTOrderBook) BestAsk() (PriceVolume, bool) {
left := b.Asks.Leftmost(b.Bids.Root)
left := b.Asks.Leftmost()
if left != nil {
return PriceVolume{Price: left.Key, Volume: left.Value}, true
}

return PriceVolume{}, false
}

Expand Down
45 changes: 34 additions & 11 deletions pkg/types/rbtree.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func (tree *RBTree) Delete(key fixedpoint.Value) bool {
y = del
} else {
y = tree.Successor(del)
if y == nil {
// prevent segmentation fault
y = Neel
}
}

if y.Left != Neel {
Expand Down Expand Up @@ -236,14 +240,13 @@ func (tree *RBTree) Size() int {
func (tree *RBTree) InsertFixup(current *RBNode) {
// A red node can't have a red parent, we need to fix it up
for current.Parent.Color == Red {
grandParent := current.Parent.Parent
if current.Parent == grandParent.Left {
uncle := grandParent.Right
if current.Parent == current.Parent.Parent.Left {
uncle := current.Parent.Parent.Right
if uncle.Color == Red {
current.Parent.Color = Black
uncle.Color = Black
grandParent.Color = Red
current = grandParent
current.Parent.Parent.Color = Red
current = current.Parent.Parent
} else { // if uncle is black
if current == current.Parent.Right {
current = current.Parent
Expand All @@ -260,8 +263,8 @@ func (tree *RBTree) InsertFixup(current *RBNode) {
current.Parent.Color = Black
uncle.Color = Black
current.Parent.Parent.Color = Red
current = current.Parent.Parent
} else {

if current == current.Parent.Left {
current = current.Parent
tree.RotateRight(current)
Expand Down Expand Up @@ -328,25 +331,41 @@ func (tree *RBTree) RotateRight(y *RBNode) {
y.Parent = x
}

func (tree *RBTree) Rightmost(current *RBNode) *RBNode {
func (tree *RBTree) Rightmost() *RBNode {
return tree.RightmostOf(tree.Root)
}

func (tree *RBTree) RightmostOf(current *RBNode) *RBNode {
for current.Right != Neel {
current = current.Right
}

if current == Neel {
return nil
}

return current
}

func (tree *RBTree) Leftmost(current *RBNode) *RBNode {
func (tree *RBTree) Leftmost() *RBNode {
return tree.LeftmostOf(tree.Root)
}

func (tree *RBTree) LeftmostOf(current *RBNode) *RBNode {
for current.Left != Neel {
current = current.Left
}

if current == Neel {
return nil
}

return current
}

func (tree *RBTree) Successor(current *RBNode) *RBNode {
if current.Right != Neel {
return tree.Leftmost(current.Right)
return tree.LeftmostOf(current.Right)
}

var newNode = current.Parent
Expand All @@ -355,6 +374,10 @@ func (tree *RBTree) Successor(current *RBNode) *RBNode {
newNode = newNode.Parent
}

if newNode == Neel {
return nil
}

return newNode
}

Expand Down Expand Up @@ -391,7 +414,7 @@ func (tree *RBTree) InorderReverse(cb func(n *RBNode) bool) {
}

func (tree *RBTree) InorderReverseOf(current *RBNode, cb func(n *RBNode) bool) {
if current != nil {
if current != Neel {
tree.InorderReverseOf(current.Right, cb)
if !cb(current) {
return
Expand All @@ -405,7 +428,7 @@ func (tree *RBTree) Postorder(cb func(n *RBNode) bool) {
}

func (tree *RBTree) PostorderOf(current *RBNode, cb func(n *RBNode) bool) {
if current != nil {
if current != Neel {
tree.PostorderOf(current.Left, cb)
tree.PostorderOf(current.Right, cb)
if !cb(current) {
Expand Down

0 comments on commit 1531f2b

Please sign in to comment.