Change rb functions to use snakeCase.

This commit is contained in:
Matthew O'Connor 2018-11-15 21:09:21 -07:00 committed by Andrew Kelley
parent ba361f31c6
commit 007783753e

View File

@ -40,7 +40,7 @@ pub const Node = struct {
} }
while (true) { while (true) {
var parent = node.get_parent(); var parent = node.getParent();
if (parent) |p| { if (parent) |p| {
if (node != p.right) if (node != p.right)
return p; return p;
@ -61,7 +61,7 @@ pub const Node = struct {
} }
while (true) { while (true) {
var parent = node.get_parent(); var parent = node.getParent();
if (parent) |p| { if (parent) |p| {
if (node != p.left) if (node != p.left)
return p; return p;
@ -71,23 +71,23 @@ pub const Node = struct {
} }
} }
pub fn is_root(node: *Node) bool { pub fn isRoot(node: *Node) bool {
return node.get_parent() == null; return node.getParent() == null;
} }
fn is_red(node: *Node) bool { fn isRed(node: *Node) bool {
return node.get_color() == Red; return node.getColor() == Red;
} }
fn is_black(node: *Node) bool { fn isBlack(node: *Node) bool {
return node.get_color() == Black; return node.getColor() == Black;
} }
fn set_parent(node: *Node, parent: ?*Node) void { fn setParent(node: *Node, parent: ?*Node) void {
node.parent_and_color = @ptrToInt(parent) | (node.parent_and_color & 1); node.parent_and_color = @ptrToInt(parent) | (node.parent_and_color & 1);
} }
fn get_parent(node: *Node) ?*Node { fn getParent(node: *Node) ?*Node {
const mask: usize = 1; const mask: usize = 1;
comptime { comptime {
assert(@alignOf(*Node) >= 2); assert(@alignOf(*Node) >= 2);
@ -95,12 +95,12 @@ pub const Node = struct {
return @intToPtr(*Node, node.parent_and_color & ~mask); return @intToPtr(*Node, node.parent_and_color & ~mask);
} }
fn set_color(node: *Node, color: Color) void { fn setColor(node: *Node, color: Color) void {
const mask: usize = 1; const mask: usize = 1;
node.parent_and_color = (node.parent_and_color & ~mask) | @enumToInt(color); node.parent_and_color = (node.parent_and_color & ~mask) | @enumToInt(color);
} }
fn get_color(node: *Node) Color { fn getColor(node: *Node) Color {
return @intToEnum(Color, @intCast(u1, node.parent_and_color & 1)); return @intToEnum(Color, @intCast(u1, node.parent_and_color & 1));
} }
@ -112,7 +112,7 @@ pub const Node = struct {
} }
} }
fn get_first(nodeconst: *Node) *Node { fn getFirst(nodeconst: *Node) *Node {
var node = nodeconst; var node = nodeconst;
while (node.left) |left| { while (node.left) |left| {
node = left; node = left;
@ -120,7 +120,7 @@ pub const Node = struct {
return node; return node;
} }
fn get_last(node: *Node) *Node { fn getLast(node: *Node) *Node {
while (node.right) |right| { while (node.right) |right| {
node = right; node = right;
} }
@ -161,15 +161,15 @@ pub const Tree = struct {
var maybe_parent: ?*Node = undefined; var maybe_parent: ?*Node = undefined;
var is_left: bool = undefined; var is_left: bool = undefined;
maybe_key = do_lookup(node, tree, &maybe_parent, &is_left); maybe_key = doLookup(node, tree, &maybe_parent, &is_left);
if (maybe_key) |key| { if (maybe_key) |key| {
return key; return key;
} }
node.left = null; node.left = null;
node.right = null; node.right = null;
node.set_color(Red); node.setColor(Red);
node.set_parent(maybe_parent); node.setParent(maybe_parent);
if (maybe_parent) |parent| { if (maybe_parent) |parent| {
parent.set_child(node, is_left); parent.set_child(node, is_left);
@ -177,58 +177,58 @@ pub const Tree = struct {
tree.root = node; tree.root = node;
} }
while (node.get_parent()) |*parent| { while (node.getParent()) |*parent| {
if (parent.*.is_black()) if (parent.*.isBlack())
break; break;
// the root is always black // the root is always black
var grandpa = parent.*.get_parent() orelse unreachable; var grandpa = parent.*.getParent() orelse unreachable;
if (parent.* == grandpa.left) { if (parent.* == grandpa.left) {
var maybe_uncle = grandpa.right; var maybe_uncle = grandpa.right;
if (maybe_uncle) |uncle| { if (maybe_uncle) |uncle| {
if (uncle.is_black()) if (uncle.isBlack())
break; break;
parent.*.set_color(Black); parent.*.setColor(Black);
uncle.set_color(Black); uncle.setColor(Black);
grandpa.set_color(Red); grandpa.setColor(Red);
node = grandpa; node = grandpa;
} else { } else {
if (node == parent.*.right) { if (node == parent.*.right) {
rotate_left(parent.*, tree); rotateLeft(parent.*, tree);
node = parent.*; node = parent.*;
parent.* = node.get_parent().?; // Just rotated parent.* = node.getParent().?; // Just rotated
} }
parent.*.set_color(Black); parent.*.setColor(Black);
grandpa.set_color(Red); grandpa.setColor(Red);
rotate_right(grandpa, tree); rotateRight(grandpa, tree);
} }
} else { } else {
var maybe_uncle = grandpa.left; var maybe_uncle = grandpa.left;
if (maybe_uncle) |uncle| { if (maybe_uncle) |uncle| {
if (uncle.is_black()) if (uncle.isBlack())
break; break;
parent.*.set_color(Black); parent.*.setColor(Black);
uncle.set_color(Black); uncle.setColor(Black);
grandpa.set_color(Red); grandpa.setColor(Red);
node = grandpa; node = grandpa;
} else { } else {
if (node == parent.*.left) { if (node == parent.*.left) {
rotate_right(parent.*, tree); rotateRight(parent.*, tree);
node = parent.*; node = parent.*;
parent.* = node.get_parent().?; // Just rotated parent.* = node.getParent().?; // Just rotated
} }
parent.*.set_color(Black); parent.*.setColor(Black);
grandpa.set_color(Red); grandpa.setColor(Red);
rotate_left(grandpa, tree); rotateLeft(grandpa, tree);
} }
} }
} }
// This was an insert, there is at least one node. // This was an insert, there is at least one node.
tree.root.?.set_color(Black); tree.root.?.setColor(Black);
return null; return null;
} }
@ -236,14 +236,14 @@ pub const Tree = struct {
var parent: *Node = undefined; var parent: *Node = undefined;
var is_left: bool = undefined; var is_left: bool = undefined;
return do_lookup(key, tree, &parent, &is_left); return doLookup(key, tree, &parent, &is_left);
} }
pub fn remove(tree: *Tree, nodeconst: *Node) void { pub fn remove(tree: *Tree, nodeconst: *Node) void {
var node = nodeconst; var node = nodeconst;
// as this has the same value as node, it is unsafe to access node after newnode // as this has the same value as node, it is unsafe to access node after newnode
var newnode: ?*Node = nodeconst; var newnode: ?*Node = nodeconst;
var maybe_parent: ?*Node = node.get_parent(); var maybe_parent: ?*Node = node.getParent();
var color: Color = undefined; var color: Color = undefined;
var next: *Node = undefined; var next: *Node = undefined;
@ -253,7 +253,7 @@ pub const Tree = struct {
parent.set_child(null, parent.left == node); parent.set_child(null, parent.left == node);
} else } else
tree.root = null; tree.root = null;
color = node.get_color(); color = node.getColor();
newnode = null; newnode = null;
} else { } else {
if (node.left == null) { if (node.left == null) {
@ -261,7 +261,7 @@ pub const Tree = struct {
} else if (node.right == null) { } else if (node.right == null) {
next = node.left.?; // Not both null as per above next = node.left.?; // Not both null as per above
} else } else
next = node.right.?.get_first(); // Just checked for null above next = node.right.?.getFirst(); // Just checked for null above
if (maybe_parent) |parent| { if (maybe_parent) |parent| {
parent.set_child(next, parent.left == node); parent.set_child(next, parent.left == node);
@ -272,39 +272,39 @@ pub const Tree = struct {
const left = node.left.?; const left = node.left.?;
const right = node.right.?; const right = node.right.?;
color = next.get_color(); color = next.getColor();
next.set_color(node.get_color()); next.setColor(node.getColor());
next.left = left; next.left = left;
left.set_parent(next); left.setParent(next);
if (next != right) { if (next != right) {
var parent = next.get_parent().?; // Was traversed via child node (right/left) var parent = next.getParent().?; // Was traversed via child node (right/left)
next.set_parent(node.get_parent()); next.setParent(node.getParent());
newnode = next.right; newnode = next.right;
parent.left = node; parent.left = node;
next.right = right; next.right = right;
right.set_parent(next); right.setParent(next);
} else { } else {
next.set_parent(maybe_parent); next.setParent(maybe_parent);
maybe_parent = next; maybe_parent = next;
newnode = next.right; newnode = next.right;
} }
} else { } else {
color = node.get_color(); color = node.getColor();
newnode = next; newnode = next;
} }
} }
if (newnode) |n| if (newnode) |n|
n.set_parent(maybe_parent); n.setParent(maybe_parent);
if (color == Red) if (color == Red)
return; return;
if (newnode) |n| { if (newnode) |n| {
n.set_color(Black); n.setColor(Black);
return; return;
} }
@ -314,69 +314,69 @@ pub const Tree = struct {
if (node == parent.left) { if (node == parent.left) {
var sibling = parent.right.?; // Same number of black nodes. var sibling = parent.right.?; // Same number of black nodes.
if (sibling.is_red()) { if (sibling.isRed()) {
sibling.set_color(Black); sibling.setColor(Black);
parent.set_color(Red); parent.setColor(Red);
rotate_left(parent, tree); rotateLeft(parent, tree);
sibling = parent.right.?; // Just rotated sibling = parent.right.?; // Just rotated
} }
if ((if (sibling.left) |n| n.is_black() else true) and if ((if (sibling.left) |n| n.isBlack() else true) and
(if (sibling.right) |n| n.is_black() else true)) (if (sibling.right) |n| n.isBlack() else true))
{ {
sibling.set_color(Red); sibling.setColor(Red);
node = parent; node = parent;
maybe_parent = parent.get_parent(); maybe_parent = parent.getParent();
continue; continue;
} }
if (if (sibling.right) |n| n.is_black() else true) { if (if (sibling.right) |n| n.isBlack() else true) {
sibling.left.?.set_color(Black); // Same number of black nodes. sibling.left.?.setColor(Black); // Same number of black nodes.
sibling.set_color(Red); sibling.setColor(Red);
rotate_right(sibling, tree); rotateRight(sibling, tree);
sibling = parent.right.?; // Just rotated sibling = parent.right.?; // Just rotated
} }
sibling.set_color(parent.get_color()); sibling.setColor(parent.getColor());
parent.set_color(Black); parent.setColor(Black);
sibling.right.?.set_color(Black); // Same number of black nodes. sibling.right.?.setColor(Black); // Same number of black nodes.
rotate_left(parent, tree); rotateLeft(parent, tree);
newnode = tree.root; newnode = tree.root;
break; break;
} else { } else {
var sibling = parent.left.?; // Same number of black nodes. var sibling = parent.left.?; // Same number of black nodes.
if (sibling.is_red()) { if (sibling.isRed()) {
sibling.set_color(Black); sibling.setColor(Black);
parent.set_color(Red); parent.setColor(Red);
rotate_right(parent, tree); rotateRight(parent, tree);
sibling = parent.left.?; // Just rotated sibling = parent.left.?; // Just rotated
} }
if ((if (sibling.left) |n| n.is_black() else true) and if ((if (sibling.left) |n| n.isBlack() else true) and
(if (sibling.right) |n| n.is_black() else true)) (if (sibling.right) |n| n.isBlack() else true))
{ {
sibling.set_color(Red); sibling.setColor(Red);
node = parent; node = parent;
maybe_parent = parent.get_parent(); maybe_parent = parent.getParent();
continue; continue;
} }
if (if (sibling.left) |n| n.is_black() else true) { if (if (sibling.left) |n| n.isBlack() else true) {
sibling.right.?.set_color(Black); // Same number of black nodes sibling.right.?.setColor(Black); // Same number of black nodes
sibling.set_color(Red); sibling.setColor(Red);
rotate_left(sibling, tree); rotateLeft(sibling, tree);
sibling = parent.left.?; // Just rotated sibling = parent.left.?; // Just rotated
} }
sibling.set_color(parent.get_color()); sibling.setColor(parent.getColor());
parent.set_color(Black); parent.setColor(Black);
sibling.left.?.set_color(Black); // Same number of black nodes sibling.left.?.setColor(Black); // Same number of black nodes
rotate_right(parent, tree); rotateRight(parent, tree);
newnode = tree.root; newnode = tree.root;
break; break;
} }
if (node.is_red()) if (node.isRed())
break; break;
} }
if (newnode) |n| if (newnode) |n|
n.set_color(Black); n.setColor(Black);
} }
/// This is a shortcut to avoid removing and re-inserting an item with the same key. /// This is a shortcut to avoid removing and re-inserting an item with the same key.
@ -386,15 +386,15 @@ pub const Tree = struct {
// I assume this can get optimized out if the caller already knows. // I assume this can get optimized out if the caller already knows.
if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual; if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual;
if (old.get_parent()) |parent| { if (old.getParent()) |parent| {
parent.set_child(new, parent.left == old); parent.set_child(new, parent.left == old);
} else } else
tree.root = new; tree.root = new;
if (old.left) |left| if (old.left) |left|
left.set_parent(new); left.setParent(new);
if (old.right) |right| if (old.right) |right|
right.set_parent(new); right.setParent(new);
new.* = old.*; new.* = old.*;
} }
@ -405,59 +405,59 @@ pub const Tree = struct {
} }
}; };
fn rotate_left(node: *Node, tree: *Tree) void { fn rotateLeft(node: *Node, tree: *Tree) void {
var p: *Node = node; var p: *Node = node;
var q: *Node = node.right orelse unreachable; var q: *Node = node.right orelse unreachable;
var parent: *Node = undefined; var parent: *Node = undefined;
if (!p.is_root()) { if (!p.isRoot()) {
parent = p.get_parent().?; parent = p.getParent().?;
if (parent.left == p) { if (parent.left == p) {
parent.left = q; parent.left = q;
} else { } else {
parent.right = q; parent.right = q;
} }
q.set_parent(parent); q.setParent(parent);
} else { } else {
tree.root = q; tree.root = q;
q.set_parent(null); q.setParent(null);
} }
p.set_parent(q); p.setParent(q);
p.right = q.left; p.right = q.left;
if (p.right) |right| { if (p.right) |right| {
right.set_parent(p); right.setParent(p);
} }
q.left = p; q.left = p;
} }
fn rotate_right(node: *Node, tree: *Tree) void { fn rotateRight(node: *Node, tree: *Tree) void {
var p: *Node = node; var p: *Node = node;
var q: *Node = node.left orelse unreachable; var q: *Node = node.left orelse unreachable;
var parent: *Node = undefined; var parent: *Node = undefined;
if (!p.is_root()) { if (!p.isRoot()) {
parent = p.get_parent().?; parent = p.getParent().?;
if (parent.left == p) { if (parent.left == p) {
parent.left = q; parent.left = q;
} else { } else {
parent.right = q; parent.right = q;
} }
q.set_parent(parent); q.setParent(parent);
} else { } else {
tree.root = q; tree.root = q;
q.set_parent(null); q.setParent(null);
} }
p.set_parent(q); p.setParent(q);
p.left = q.right; p.left = q.right;
if (p.left) |left| { if (p.left) |left| {
left.set_parent(p); left.setParent(p);
} }
q.right = p; q.right = p;
} }
fn do_lookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node { fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
var maybe_node: ?*Node = tree.root; var maybe_node: ?*Node = tree.root;
pparent.* = null; pparent.* = null;