// delete removes a range from the range tree. // Since this tree is not stored in memory but persisted through the ranges, in // place deletion is not possible. Instead, we use the helper function // swapNodes above. func (tc *treeContext) delete(node *proto.RangeTreeNode) error { key := node.Key if node.LeftKey != nil && node.RightKey != nil { left, err := tc.getNode(node.LeftKey) if err != nil { return err } predecessor, err := tc.getMaxNode(left) if err != nil { return err } node, _, err = tc.swapNodes(node, predecessor) if err != nil { return err } } // Node will always have at most one child. var child *proto.RangeTreeNode var err error if node.LeftKey != nil { if child, err = tc.getNode(node.LeftKey); err != nil { return err } } else if node.RightKey != nil { if child, err = tc.getNode(node.RightKey); err != nil { return err } } if !isRed(node) { // Paint the node to the color of the child node. node.Black = !isRed(child) tc.setNode(node) if err := tc.deleteCase1(node); err != nil { return err } } if _, err := tc.replaceNode(node, child); err != nil { return err } // Always set the root back to black if node, err = tc.getNode(node.Key); err != nil { return err } if child != nil && node.ParentKey == nil { if child, err = tc.getNode(child.Key); err != nil { return err } child.Black = true tc.setNode(child) } tc.dropNode(key) return nil }
// insertCase1 handles the case when the inserted node is the root node. func (tc *treeContext) insertCase1(node *proto.RangeTreeNode) error { if node.ParentKey == nil { node.Black = true tc.setNode(node) return nil } return tc.insertCase2(node) }
// rotateRight performs a right rotation around the node. func (tc *treeContext) rotateRight(node *proto.RangeTreeNode) (*proto.RangeTreeNode, error) { left, err := tc.getNode(node.LeftKey) if err != nil { return nil, err } if left.Black { return nil, util.Error("rotating a black node") } node.LeftKey = left.RightKey left.RightKey = &node.Key left.Black = node.Black node.Black = false tc.setNode(node) tc.setNode(left) return left, nil }
// rotateLeft performs a left rotation around the node. func (tc *treeContext) rotateLeft(node *proto.RangeTreeNode) (*proto.RangeTreeNode, error) { right, err := tc.getNode(node.RightKey) if err != nil { return nil, err } if right.Black { return nil, util.Error("rotating a black node") } node.RightKey = right.LeftKey right.LeftKey = &node.Key right.Black = node.Black node.Black = false tc.setNode(node) tc.setNode(right) return right, nil }
// flip swaps the color of the node and both of its children. Both those // children must exist. func (tc *treeContext) flip(node *proto.RangeTreeNode) (*proto.RangeTreeNode, error) { left, err := tc.getNode(node.LeftKey) if err != nil { return nil, err } right, err := tc.getNode(node.RightKey) if err != nil { return nil, err } node.Black = !node.Black left.Black = !left.Black right.Black = !right.Black tc.setNode(node) tc.setNode(left) tc.setNode(right) return node, nil }