// replaceNode cuts a node away form its parent, substituting a new node or // nil. The updated new node is returned. Note that this does not in fact alter // the old node in any way, but only the old node's parent and the new node. func (tc *treeContext) replaceNode(oldNode, newNode *roachpb.RangeTreeNode) (*roachpb.RangeTreeNode, *roachpb.Error) { if oldNode.ParentKey == nil { if newNode == nil { return nil, roachpb.NewErrorf("cannot replace the root node with nil") } // Update the root key if this was the root. tc.setRootKey(newNode.Key) } else { oldParent, pErr := tc.getNode(oldNode.ParentKey) if pErr != nil { return nil, pErr } if oldParent.LeftKey != nil && oldNode.Key.Equal(oldParent.LeftKey) { if newNode == nil { oldParent.LeftKey = nil } else { oldParent.LeftKey = newNode.Key } } else { if newNode == nil { oldParent.RightKey = nil } else { oldParent.RightKey = newNode.Key } } tc.setNode(oldParent) } if newNode != nil { newNode.ParentKey = oldNode.ParentKey tc.setNode(newNode) } return newNode, nil }
// insert performs the insertion of a new node into the tree. It walks the tree // until it finds the correct location. It will fail if the node already exists // as that case should not occur. After inserting the node, it checks all insert // cases to ensure the tree is balanced and adjusts it if needed. func (tc *treeContext) insert(node *roachpb.RangeTreeNode) *roachpb.Error { if tc.tree.RootKey == nil { tc.setRootKey(node.Key) } else { // Walk the tree to find the right place to insert the new node. currentKey := tc.tree.RootKey for { currentNode, pErr := tc.getNode(currentKey) if pErr != nil { return pErr } if node.Key.Equal(currentNode.Key) { return roachpb.NewErrorf("key %s already exists in the range tree", node.Key) } if node.Key.Less(currentNode.Key) { if currentNode.LeftKey == nil { currentNode.LeftKey = node.Key tc.setNode(currentNode) break } else { currentKey = currentNode.LeftKey } } else { if currentNode.RightKey == nil { currentNode.RightKey = node.Key tc.setNode(currentNode) break } else { currentKey = currentNode.RightKey } } } node.ParentKey = currentKey tc.setNode(node) } return tc.insertCase1(node) }
// rotateRight performs a right rotation around the node. func (tc *treeContext) rotateRight(node *roachpb.RangeTreeNode) (*roachpb.RangeTreeNode, *roachpb.Error) { left, pErr := tc.getNode(node.LeftKey) if pErr != nil { return nil, pErr } left, pErr = tc.replaceNode(node, left) if pErr != nil { return nil, pErr } node.LeftKey = left.RightKey if left.RightKey != nil { leftRight, pErr := tc.getNode(left.RightKey) if pErr != nil { return nil, pErr } leftRight.ParentKey = node.Key tc.setNode(leftRight) } left.RightKey = node.Key node.ParentKey = left.Key tc.setNode(left) tc.setNode(node) return left, nil }
// rotateLeft performs a left rotation around the node. func (tc *treeContext) rotateLeft(node *roachpb.RangeTreeNode) (*roachpb.RangeTreeNode, *roachpb.Error) { right, pErr := tc.getNode(node.RightKey) if pErr != nil { return nil, pErr } right, pErr = tc.replaceNode(node, right) if pErr != nil { return nil, pErr } node.RightKey = right.LeftKey if right.LeftKey != nil { rightLeft, pErr := tc.getNode(right.LeftKey) if pErr != nil { return nil, pErr } rightLeft.ParentKey = node.Key tc.setNode(rightLeft) } right.LeftKey = node.Key node.ParentKey = right.Key tc.setNode(right) tc.setNode(node) return right, nil }