in hashring/rbtree.go [170:248]
func (t *redBlackTree) Delete(key keytype) bool {
if t.root == nil {
return false
}
var head = &redBlackNode{red: true} // fake red node to push down
var node = head
var parent *redBlackNode //parent
var gparent *redBlackNode //grandparent
var found *redBlackNode
var dir = true
node.right = t.root
for node.Child(dir) != nil {
last := dir
// update helpers
gparent = parent
parent = node
node = node.Child(dir)
cmp := node.key.Compare(key)
dir = cmp < 0
// save node if found
if cmp == 0 {
found = node
}
// pretend to push red node down
if !isRed(node) && !isRed(node.Child(dir)) {
if isRed(node.Child(!dir)) {
sr := singleRotate(node, dir)
parent.setChild(last, sr)
parent = sr
} else {
sibling := parent.Child(!last)
if sibling != nil {
if !isRed(sibling.Child(!last)) && !isRed(sibling.Child(last)) {
// flip colors
parent.red = false
sibling.red, node.red = true, true
} else {
dir2 := gparent.right == parent
if isRed(sibling.Child(last)) {
gparent.setChild(dir2, doubleRotate(parent, last))
} else if isRed(sibling.Child(!last)) {
gparent.setChild(dir2, singleRotate(parent, last))
}
gpc := gparent.Child(dir2)
gpc.red = true
node.red = true
gpc.left.red, gpc.right.red = false, false
}
}
}
}
}
// get rid of node if we've found one
if found != nil {
found.key = node.key
found.value = node.value
parent.setChild(parent.right == node, node.Child(node.left == nil))
t.size--
}
t.root = head.right
if t.root != nil {
t.root.red = false
}
return found != nil
}