diff --git a/src/main.zig b/src/main.zig index 69b8a34..a4c3aed 100644 --- a/src/main.zig +++ b/src/main.zig @@ -340,21 +340,6 @@ const BTree = struct { self.ally.destroy(self); } - fn push_value(self: *Leaf, value: u32) void { - std.debug.assert(self.len < CAPACITY); - var tmp = value; - for (self.get_values()) |*val| { - if (val.* < value) { - continue; - } - const t = val.*; - val.* = tmp; - tmp = t; - } - self.values[self.len] = tmp; - self.len = self.len + 1; - } - const SplitResult = struct { // attached, old node that may be modified left: *Leaf, @@ -372,10 +357,13 @@ const BTree = struct { if (child.left.get_values()[0] < middle) { // the left node is already attached to the tree in the correct place + // check if the rightmost value of the right child is smaller than the parent middle if (child.right.get_values()[child.right.len - 1] < middle) { @ptrCast(*Node, parent.left).insert_node(NodeOrLeaf.from_leaf(child.right)); - } else { + } else if (child.right.get_values()[0] > middle) { @ptrCast(*Node, parent.right).insert_node(NodeOrLeaf.from_leaf(child.right)); + } else { + std.debug.print("AAAAAAAAAAA something bad", .{}); } } else { // if the child left component is in the parent right, so must the child right @@ -419,8 +407,8 @@ const BTree = struct { const leaf = self; if (leaf.len < CAPACITY) { - std.debug.print("pushing value {} into leaf ", .{value}); - self.dbg(); + std.debug.print("pushing value {} into ", .{value}); + NodeOrLeaf.from_leaf(self).dbg(); std.debug.print("\n", .{}); NodeOrLeaf.from_leaf(leaf).push_value(value); @@ -428,7 +416,7 @@ const BTree = struct { std.debug.print("splitting node ", .{}); self.dbg(); const split = try leaf.split_at(value); - std.debug.print("into [", .{}); + std.debug.print(" into [ ", .{}); split.left.dbg(); std.debug.print(", {}, ", .{split.middle}); split.right.dbg(); @@ -438,13 +426,13 @@ const BTree = struct { // parent can only throw split if it has no parent, so we just pass it back along to the top? const result = try parent.parent.as_leaf().insert_value(split.middle); - if (result) |for_root| { + if (result) |parent_split| { std.debug.print("double split\n", .{}); - return SplitResult.concat(for_root, split); + return SplitResult.concat(parent_split, split); + } else { + parent.parent.insert_node(NodeOrLeaf.from_leaf(split.right)); } - - parent.parent.insert_node(NodeOrLeaf.from_leaf(split.right)); } else { return split; } @@ -553,6 +541,24 @@ test "btree insert" { tree.dbg(); } +test "btree rand insert" { + std.debug.print("random insertions\n", .{}); + + var tree = BTree.create(std.testing.allocator); + defer tree.destroy(); + + var rng = std.rand.DefaultPrng.init(0); + + for (0..100) |_| { + // const i = rng.random().intRangeAtMost(u32, 0, 512); + const i = rng.random().int(u32); + tree.insert(i) catch { + std.debug.print("{} already present - ignoring\n", .{i}); + }; + } + tree.dbg(); +} + test "btree new" { std.debug.print("testing insertion\n", .{}); var tree = BTree.create(std.testing.allocator);