most/least significant element tests/accessors

This commit is contained in:
Janis 2023-03-18 17:13:18 +01:00
parent b190719970
commit 482f01ed5e

View file

@ -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 { fn dbg(self: NodeOrLeaf) void {
switch (self) { switch (self) {
.internal => |node| { .internal => |node| {
@ -343,6 +407,12 @@ const BTree = struct {
const edges = self.get_edges()[0..values.len]; const edges = self.get_edges()[0..values.len];
std.debug.print("{{ ", .{}); std.debug.print("{{ ", .{});
std.debug.print("[{}] ", .{self.leaf.level}); 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| { for (values, edges) |v, e| {
if (e) |edge| { if (e) |edge| {
edge.dbg(); edge.dbg();
@ -458,6 +528,11 @@ const BTree = struct {
Leaf: struct { leaf: *Leaf, idx: u16 }, Leaf: struct { leaf: *Leaf, idx: u16 },
}; };
fn remove_key(self: *Leaf, key: u32) void {
_ = self;
_ = key;
}
fn find_key(self: *Leaf, key: u32) SearchResult { fn find_key(self: *Leaf, key: u32) SearchResult {
for (self.get_values(), 0..) |v, i| { for (self.get_values(), 0..) |v, i| {
if (key < v) { if (key < v) {
@ -516,17 +591,6 @@ pub fn main() !void {
try bw.flush(); // don't forget to flush! 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 { fn printValues(leaf: *BTree.Leaf) void {
const values = leaf.get_values(); const values = leaf.get_values();
std.debug.print("{any}\n", .{values}); std.debug.print("{any}\n", .{values});
@ -608,3 +672,40 @@ test "btree rand insert" {
tree.dbg(); 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 });
}
}