aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Landden <shawn@git.icu>2020-01-19 22:08:05 +0400
committerShawn Landden <shawn@git.icu>2020-01-19 22:09:56 +0400
commite19008292222d37b3a08a4e6a9d41553ecfcfd7e (patch)
treebe696a18c9930da6492254a6bdae4d35ffc81662
parentde07ca77e7310af23fa494defbf7cc235afdac68 (diff)
downloadzig-e19008292222d37b3a08a4e6a9d41553ecfcfd7e.tar.gz
zig-e19008292222d37b3a08a4e6a9d41553ecfcfd7e.zip
rb: *breaking* make API thread-safe
use @fieldParentPtr to access your context fields, which lie if you struct that contains a rb.Tree member (without a pointer). Also simplifies the init() function so rb.Tree can be initialized in a single line, without having to use "undefined".
-rw-r--r--lib/std/rb.zig25
1 files changed, 12 insertions, 13 deletions
diff --git a/lib/std/rb.zig b/lib/std/rb.zig
index 0e87eb1eb6..0fefa033a9 100644
--- a/lib/std/rb.zig
+++ b/lib/std/rb.zig
@@ -132,7 +132,7 @@ pub const Node = struct {
pub const Tree = struct {
root: ?*Node,
- compareFn: fn (*Node, *Node) Order,
+ compareFn: fn (*Node, *Node, *Tree) Order,
/// If you have a need for a version that caches this, please file a bug.
pub fn first(tree: *Tree) ?*Node {
@@ -389,7 +389,7 @@ pub const Tree = struct {
var new = newconst;
// I assume this can get optimized out if the caller already knows.
- if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual;
+ if (tree.compareFn(old, new, tree) != .eq) return ReplaceError.NotEqual;
if (old.getParent()) |parent| {
parent.setChild(new, parent.left == old);
@@ -404,9 +404,11 @@ pub const Tree = struct {
new.* = old.*;
}
- pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void {
- tree.root = null;
- tree.compareFn = f;
+ pub fn init(f: fn (*Node, *Node, *Tree) Order) Tree {
+ return Tree{
+ .root = null,
+ .compareFn = f,
+ };
}
};
@@ -469,7 +471,7 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
is_left.* = false;
while (maybe_node) |node| {
- const res = tree.compareFn(node, key);
+ const res = tree.compareFn(node, key, tree);
if (res == .eq) {
return node;
}
@@ -498,7 +500,7 @@ fn testGetNumber(node: *Node) *testNumber {
return @fieldParentPtr(testNumber, "node", node);
}
-fn testCompare(l: *Node, r: *Node) Order {
+fn testCompare(l: *Node, r: *Node, contextIgnored: *Tree) Order {
var left = testGetNumber(l);
var right = testGetNumber(r);
@@ -518,7 +520,7 @@ test "rb" {
return error.SkipZigTest;
}
- var tree: Tree = undefined;
+ var tree = Tree.init(testCompare);
var ns: [10]testNumber = undefined;
ns[0].value = 42;
ns[1].value = 41;
@@ -534,7 +536,6 @@ test "rb" {
var dup: testNumber = undefined;
dup.value = 32345;
- tree.init(testCompare);
_ = tree.insert(&ns[1].node);
_ = tree.insert(&ns[2].node);
_ = tree.insert(&ns[3].node);
@@ -557,8 +558,7 @@ test "rb" {
}
test "inserting and looking up" {
- var tree: Tree = undefined;
- tree.init(testCompare);
+ var tree = Tree.init(testCompare);
var number: testNumber = undefined;
number.value = 1000;
_ = tree.insert(&number.node);
@@ -582,8 +582,7 @@ test "multiple inserts, followed by calling first and last" {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
- var tree: Tree = undefined;
- tree.init(testCompare);
+ var tree = Tree.init(testCompare);
var zeroth: testNumber = undefined;
zeroth.value = 0;
var first: testNumber = undefined;