authorgravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2020-01-19 22:08:05+04:00
committergravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2020-01-19 22:09:56+04:00
loge19008292222d37b3a08a4e6a9d41553ecfcfd7e
treebe696a18c9930da6492254a6bdae4d35ffc81662
parentde07ca77e7310af23fa494defbf7cc235afdac68

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".

1 files changed, 12 insertions(+), 13 deletions(-)

lib/std/rb.zig+12-13
...@@ -132,7 +132,7 @@ pub const Node = struct {...@@ -132,7 +132,7 @@ pub const Node = struct {
132132
133pub const Tree = struct {133pub const Tree = struct {
134 root: ?*Node,134 root: ?*Node,
135 compareFn: fn (*Node, *Node) Order,135 compareFn: fn (*Node, *Node, *Tree) Order,
136136
137 /// If you have a need for a version that caches this, please file a bug.137 /// If you have a need for a version that caches this, please file a bug.
138 pub fn first(tree: *Tree) ?*Node {138 pub fn first(tree: *Tree) ?*Node {
...@@ -389,7 +389,7 @@ pub const Tree = struct {...@@ -389,7 +389,7 @@ pub const Tree = struct {
389 var new = newconst;389 var new = newconst;
390390
391 // I assume this can get optimized out if the caller already knows.391 // I assume this can get optimized out if the caller already knows.
392 if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual;392 if (tree.compareFn(old, new, tree) != .eq) return ReplaceError.NotEqual;
393393
394 if (old.getParent()) |parent| {394 if (old.getParent()) |parent| {
395 parent.setChild(new, parent.left == old);395 parent.setChild(new, parent.left == old);
...@@ -404,9 +404,11 @@ pub const Tree = struct {...@@ -404,9 +404,11 @@ pub const Tree = struct {
404 new.* = old.*;404 new.* = old.*;
405 }405 }
406406
407 pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void {407 pub fn init(f: fn (*Node, *Node, *Tree) Order) Tree {
408 tree.root = null;408 return Tree{
409 tree.compareFn = f;409 .root = null,
410 .compareFn = f,
411 };
410 }412 }
411};413};
412414
...@@ -469,7 +471,7 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {...@@ -469,7 +471,7 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
469 is_left.* = false;471 is_left.* = false;
470472
471 while (maybe_node) |node| {473 while (maybe_node) |node| {
472 const res = tree.compareFn(node, key);474 const res = tree.compareFn(node, key, tree);
473 if (res == .eq) {475 if (res == .eq) {
474 return node;476 return node;
475 }477 }
...@@ -498,7 +500,7 @@ fn testGetNumber(node: *Node) *testNumber {...@@ -498,7 +500,7 @@ fn testGetNumber(node: *Node) *testNumber {
498 return @fieldParentPtr(testNumber, "node", node);500 return @fieldParentPtr(testNumber, "node", node);
499}501}
500502
501fn testCompare(l: *Node, r: *Node) Order {503fn testCompare(l: *Node, r: *Node, contextIgnored: *Tree) Order {
502 var left = testGetNumber(l);504 var left = testGetNumber(l);
503 var right = testGetNumber(r);505 var right = testGetNumber(r);
504506
...@@ -518,7 +520,7 @@ test "rb" {...@@ -518,7 +520,7 @@ test "rb" {
518 return error.SkipZigTest;520 return error.SkipZigTest;
519 }521 }
520522
521 var tree: Tree = undefined;523 var tree = Tree.init(testCompare);
522 var ns: [10]testNumber = undefined;524 var ns: [10]testNumber = undefined;
523 ns[0].value = 42;525 ns[0].value = 42;
524 ns[1].value = 41;526 ns[1].value = 41;
...@@ -534,7 +536,6 @@ test "rb" {...@@ -534,7 +536,6 @@ test "rb" {
534 var dup: testNumber = undefined;536 var dup: testNumber = undefined;
535 dup.value = 32345;537 dup.value = 32345;
536538
537 tree.init(testCompare);
538 _ = tree.insert(&ns[1].node);539 _ = tree.insert(&ns[1].node);
539 _ = tree.insert(&ns[2].node);540 _ = tree.insert(&ns[2].node);
540 _ = tree.insert(&ns[3].node);541 _ = tree.insert(&ns[3].node);
...@@ -557,8 +558,7 @@ test "rb" {...@@ -557,8 +558,7 @@ test "rb" {
557}558}
558559
559test "inserting and looking up" {560test "inserting and looking up" {
560 var tree: Tree = undefined;561 var tree = Tree.init(testCompare);
561 tree.init(testCompare);
562 var number: testNumber = undefined;562 var number: testNumber = undefined;
563 number.value = 1000;563 number.value = 1000;
564 _ = tree.insert(&number.node);564 _ = tree.insert(&number.node);
...@@ -582,8 +582,7 @@ test "multiple inserts, followed by calling first and last" {...@@ -582,8 +582,7 @@ test "multiple inserts, followed by calling first and last" {
582 // TODO https://github.com/ziglang/zig/issues/3288582 // TODO https://github.com/ziglang/zig/issues/3288
583 return error.SkipZigTest;583 return error.SkipZigTest;
584 }584 }
585 var tree: Tree = undefined;585 var tree = Tree.init(testCompare);
586 tree.init(testCompare);
587 var zeroth: testNumber = undefined;586 var zeroth: testNumber = undefined;
588 zeroth.value = 0;587 zeroth.value = 0;
589 var first: testNumber = undefined;588 var first: testNumber = undefined;