This commit is contained in:
Janis 2023-03-18 02:14:36 +01:00
parent c2d0022cf8
commit c7c71d0c3f

View file

@ -75,6 +75,7 @@ const BTree = struct {
leaf: *Leaf,
fn destroy(self: NodeOrLeaf) void {
std.debug.print("destroying node\n", .{});
switch (self) {
.internal => |node| {
node.destroy();
@ -267,10 +268,7 @@ const BTree = struct {
}
if (self.get_edges()[idx]) |edge| {
std.debug.print("edge already present between {} and {}\nedge already present:", .{
self_leaf.get_values()[@max(idx - 1, 0)],
self_leaf.get_values()[@min(idx + 1, self_leaf.len - 1)],
});
std.debug.print("edge already present:", .{});
child.dbg();
std.debug.print(" - ", .{});
edge.dbg();
@ -281,6 +279,52 @@ const BTree = struct {
}
}
const InsertResultTag = enum {
Split,
RightFromParent,
};
const InsertResult = union(InsertResultTag) {
Split: Leaf.SplitResult,
RightFromParent: *Leaf,
};
fn insert_split(self: *Node, split: Leaf.SplitResult) !?Leaf.SplitResult {
std.debug.print("inserting split\n", .{});
const leaf = self.as_leaf();
const value = split.middle;
if (leaf.len < CAPACITY) {
std.debug.print("pushing value {} into ", .{value});
self.dbg();
std.debug.print("\n", .{});
NodeOrLeaf.from_leaf(leaf).push_value(value);
self.insert_node(NodeOrLeaf.from_leaf(split.right));
} else {
std.debug.print("splitting node ", .{});
self.dbg();
var parent_split = try leaf.split_at(value);
std.debug.print(" into [ ", .{});
split.left.dbg();
std.debug.print(", {}, ", .{split.middle});
split.right.dbg();
std.debug.print("]\n", .{});
std.debug.print("concatinating splits\n", .{});
const next_split = Leaf.SplitResult.concat(parent_split, split);
if (leaf.parent) |parent| {
return parent.parent.insert_split(next_split);
} else {
return split;
}
}
return null;
}
fn get_edges(self: *Node) []?NodeOrLeaf {
const len = self.leaf.len + 1;
return self.edges[0..len];
@ -386,9 +430,9 @@ const BTree = struct {
}
std.debug.print(" into [", .{});
parent.left.dbg();
NodeOrLeaf.from_leaf(parent.left).dbg();
std.debug.print(", {}, ", .{parent.middle});
parent.right.dbg();
NodeOrLeaf.from_leaf(parent.right).dbg();
std.debug.print(" ]\n", .{});
return parent;
@ -443,23 +487,12 @@ const BTree = struct {
split.right.dbg();
std.debug.print("]\n", .{});
// recursively solve splits
var prnt = leaf.parent;
while (prnt) |parent| {
const maybe_parent_split = try parent.parent.as_leaf().insert_value(split.middle);
if (maybe_parent_split) |parent_split| {
std.debug.print("concatinating splits\n", .{});
split = SplitResult.concat(parent_split, split);
prnt = parent.parent.as_leaf().parent;
if (leaf.parent) |parent| {
return parent.parent.insert_split(split);
} else {
parent.parent.insert_node(NodeOrLeaf.from_leaf(split.right));
return null;
}
}
return split;
}
}
return null;
}
@ -503,66 +536,40 @@ fn printValues(leaf: *BTree.Leaf) void {
std.debug.print("{any}\n", .{values});
}
test "leaf split" {
std.debug.print("testing splitting\n", .{});
// test "leaf split" {
// std.debug.print("testing splitting\n", .{});
var tree = BTree.create(std.testing.allocator);
defer tree.destroy();
try tree.insert(2);
try tree.insert(4);
try tree.insert(6);
try tree.insert(3);
try tree.insert(7);
std.debug.print("before split:", .{});
printValues(tree.root.?.as_leaf());
// var tree = BTree.create(std.testing.allocator);
// defer tree.destroy();
// try tree.insert(2);
// try tree.insert(4);
// try tree.insert(6);
// try tree.insert(3);
// try tree.insert(7);
// std.debug.print("before split:", .{});
// printValues(tree.root.?.as_leaf());
const split = try tree.root.?.as_leaf().split_at(5);
// const split = try tree.root.?.as_leaf().split_at(5);
std.debug.print("after split:", .{});
printValues(tree.root.?.as_leaf());
// std.debug.print("after split:", .{});
// printValues(tree.root.?.as_leaf());
std.debug.print("split: {?}\n", .{split});
tree.ally.destroy(split.right);
return error.SkipZigTest;
}
// std.debug.print("split: {?}\n", .{split});
// tree.ally.destroy(split.right);
// }
test "btree insert" {
std.debug.print("testing insertion\n", .{});
var tree = BTree.create(std.testing.allocator);
defer tree.destroy();
try tree.insert(10);
try tree.insert(4);
try tree.insert(6);
try tree.insert(3);
try tree.insert(9);
try tree.insert(8);
tree.dbg();
try tree.insert(11);
tree.dbg();
try tree.insert(12);
try tree.insert(16);
tree.dbg();
try tree.insert(1);
try tree.insert(2);
try tree.insert(0);
try tree.insert(5);
tree.dbg();
try tree.insert(25);
try tree.insert(43);
try tree.insert(40);
try tree.insert(42);
tree.dbg();
try tree.insert(22);
try tree.insert(44);
try tree.insert(60);
try tree.insert(52);
tree.dbg();
try tree.insert(71);
try tree.insert(72);
try tree.insert(73);
try tree.insert(74);
tree.dbg();
}
// test "btree insert" {
// std.debug.print("testing insertion\n", .{});
// var tree = BTree.create(std.testing.allocator);
// defer tree.destroy();
// try tree.insert(10);
// try tree.insert(4);
// try tree.insert(6);
// try tree.insert(3);
// try tree.insert(9);
// try tree.insert(8);
// tree.dbg();
// }
test "btree seq insert" {
std.debug.print("sequential insertions\n", .{});
@ -595,27 +602,3 @@ test "btree seq insert" {
// }
// tree.dbg();
// }
test "btree new" {
std.debug.print("testing insertion\n", .{});
var tree = BTree.create(std.testing.allocator);
defer tree.destroy();
try tree.insert(5);
printValues(tree.root.?.as_leaf());
try tree.insert(4);
printValues(tree.root.?.as_leaf());
try tree.insert(6);
printValues(tree.root.?.as_leaf());
try tree.insert(3);
printValues(tree.root.?.as_leaf());
try tree.insert(7);
printValues(tree.root.?.as_leaf());
//try tree.insert(8);
}
test "simple test" {
var list = std.ArrayList(i32).init(std.testing.allocator);
defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
try list.append(42);
try std.testing.expectEqual(@as(i32, 42), list.pop());
}