From 482f01ed5ebdcd4e0a9aa764ec4fbf265549f927 Mon Sep 17 00:00:00 2001 From: Janis Date: Sat, 18 Mar 2023 17:13:18 +0100 Subject: [PATCH] most/least significant element tests/accessors --- src/main.zig | 123 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 112 insertions(+), 11 deletions(-) diff --git a/src/main.zig b/src/main.zig index 93defb2..7916e06 100644 --- a/src/main.zig +++ b/src/main.zig @@ -237,6 +237,70 @@ const BTree = struct { } } + fn find_most_significant_key(self: NodeOrLeaf) Leaf.SearchResult { + var node = self; + while (true) { + switch (node.force()) { + .internal => |internal| { + if (internal.get_edges()[internal.leaf.len]) |child| { + node = child; + continue; + } + }, + .leaf => |leaf| { + return .{ .Leaf = .{ .leaf = leaf, .idx = leaf.len - 1 } }; + }, + } + } + } + + fn find_least_significant_key(self: NodeOrLeaf) Leaf.SearchResult { + var node = self; + while (true) { + switch (node.force()) { + .internal => |internal| { + if (internal.get_edges()[0]) |child| { + node = child; + continue; + } + }, + .leaf => |leaf| { + return .{ .Leaf = .{ .leaf = leaf, .idx = 0 } }; + }, + } + } + } + + fn get_most_significant_value(self: NodeOrLeaf) u32 { + switch (self.force()) { + .internal => |node| { + if (node.get_edges()[node.leaf.len]) |edge| { + return edge.get_most_significant_value(); + } else { + return node.as_leaf().get_values()[node.leaf.len - 1]; + } + }, + .leaf => |node| { + return node.get_values()[node.len - 1]; + }, + } + } + + fn get_least_significant_value(self: NodeOrLeaf) u32 { + switch (self.force()) { + .internal => |node| { + if (node.get_edges()[0]) |edge| { + return edge.get_least_significant_value(); + } else { + return node.as_leaf().get_values()[0]; + } + }, + .leaf => |node| { + return node.get_values()[0]; + }, + } + } + fn dbg(self: NodeOrLeaf) void { switch (self) { .internal => |node| { @@ -343,6 +407,12 @@ const BTree = struct { const edges = self.get_edges()[0..values.len]; std.debug.print("{{ ", .{}); std.debug.print("[{}] ", .{self.leaf.level}); + + // an internal node should have at least B elements + if (self.leaf.len < MIN_AFTER_SPLIT) { + std.debug.print("[E] ", .{}); + } + for (values, edges) |v, e| { if (e) |edge| { edge.dbg(); @@ -458,6 +528,11 @@ const BTree = struct { Leaf: struct { leaf: *Leaf, idx: u16 }, }; + fn remove_key(self: *Leaf, key: u32) void { + _ = self; + _ = key; + } + fn find_key(self: *Leaf, key: u32) SearchResult { for (self.get_values(), 0..) |v, i| { if (key < v) { @@ -516,17 +591,6 @@ pub fn main() !void { try bw.flush(); // don't forget to flush! } -test "btree leaf" { - std.testing.refAllDeclsRecursive(BTree); - std.testing.refAllDeclsRecursive(BTree.Leaf); - - var leaf = BTree.Leaf{ .ally = std.testing.allocator, .parent = null, .len = 2, .values = [_]u32{ 5, 6, undefined, undefined, undefined } }; - const values = leaf.get_values(); - - std.debug.print("{?}\n", .{leaf}); - std.debug.print("{any}\n", .{values}); -} - fn printValues(leaf: *BTree.Leaf) void { const values = leaf.get_values(); std.debug.print("{any}\n", .{values}); @@ -608,3 +672,40 @@ test "btree rand insert" { tree.dbg(); } + +test "btree least most sig value" { + std.debug.print("least/most significant values\n", .{}); + + var tree = BTree.create(std.testing.allocator); + defer tree.destroy(); + + for (0..100) |i| { + tree.insert(@intCast(u32, i)) catch { + std.debug.print("{} already present - ignoring\n", .{i}); + }; + } + tree.dbg(); + std.debug.print("\n", .{}); + + { + const l = tree.root.?.get_least_significant_value(); + const r = tree.root.?.get_most_significant_value(); + std.debug.print("{} < {}\n", .{ l, r }); + std.debug.assert(l == 0); + std.debug.assert(r == 99); + } + + { + const node = tree.root.?; + const l = node.find_least_significant_key(); + const r = node.find_most_significant_key(); + std.debug.print("{} < {}\n", .{ l, r }); + } + + { + const node = tree.root.?.internal.edges[1].?.force(); + const l = node.get_least_significant_value(); + const r = node.get_most_significant_value(); + std.debug.print("{} < {}\n", .{ l, r }); + } +}