From 94f42f24c5a57ff37d116c90872fe9b3e9958834 Mon Sep 17 00:00:00 2001 From: Janis Date: Fri, 17 Mar 2023 20:08:51 +0100 Subject: [PATCH] insert with lookup 3rd lvl is broken --- src/main.zig | 120 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 29 deletions(-) diff --git a/src/main.zig b/src/main.zig index cce0a46..a7a8313 100644 --- a/src/main.zig +++ b/src/main.zig @@ -22,16 +22,26 @@ const BTree = struct { self.dbg(); if (self.root) |*root| { - const result = try root.as_leaf().insert_value(value); - if (result) |split| { - // create new node which will replace self. - const parent = try Node.create(self.ally); - parent.leaf.level = split.left.level + 1; - parent.leaf.push_value(split.middle); - parent.insert_node(NodeOrLeaf.from_leaf(split.left)); - parent.insert_node(NodeOrLeaf.from_leaf(split.right)); + const search = root.find_key(value); - self.root = .{ .internal = parent }; + switch (search) { + .Leaf => |node| { + std.debug.print("key already present: {}", .{node}); + return error.Occupied; + }, + .Edge => |edge| { + const result = try edge.leaf.insert_value(value); + if (result) |split| { + // create new node which will replace self. + const parent = try Node.create(self.ally); + parent.leaf.level = split.left.level + 1; + parent.leaf.push_value(split.middle); + parent.insert_node(NodeOrLeaf.from_leaf(split.left)); + parent.insert_node(NodeOrLeaf.from_leaf(split.right)); + + self.root = .{ .internal = parent }; + } + }, } } else { var leaf: *Leaf = try self.ally.create(Leaf); @@ -94,6 +104,32 @@ const BTree = struct { } } + fn find_key(self: NodeOrLeaf, key: u32) Leaf.SearchResult { + var leaf = self.as_leaf(); + while (true) { + const search = leaf.find_key(key); + + switch (search) { + .Leaf => { + return search; + }, + .Edge => |edge| { + const node = NodeOrLeaf.from_leaf(edge.leaf); + switch (node) { + .internal => |internal| { + if (internal.get_edges()[edge.idx]) |child| { + leaf = child.as_leaf(); + continue; + } + }, + .leaf => {}, + } + return search; + }, + } + } + } + fn dbg(self: NodeOrLeaf) void { switch (self) { .internal => |node| { @@ -237,11 +273,12 @@ const BTree = struct { } const SplitResult = struct { - // attached + // attached, old node that may be modified left: *Leaf, // lose value, previously attacked, must be inserted + // if we go all the way to the top, the root node must have some value and this is it middle: u32, - // free floating leaf, must be attached + // new, free floating leaf, must be attached right: *Leaf, }; @@ -254,36 +291,51 @@ const BTree = struct { } } - std.debug.assert(idx > 0 and idx < CAPACITY - 1); + std.debug.assert(self.len == CAPACITY); + //std.debug.assert(idx > 0 and idx < CAPACITY - 1); var new = try Leaf.create(self.ally); new.level = self.level; var middle: u32 = undefined; + new.len = B - 1; + std.mem.copy(u32, &new.values, self.values[B..]); + middle = self.values[B - 1]; + self.len = B - 1; + // take from right half - if (idx > B) { - new.len = self.len - (idx + 1); - std.mem.copy(u32, &new.values, self.values[(idx + 1)..self.len]); - - middle = self.values[idx]; - - self.len = idx; - self.push_value(value); - } else { - // take from left half - new.len = self.len - (idx); - std.mem.copy(u32, &new.values, self.values[idx..self.len]); - + if (idx >= B) { new.push_value(value); - - middle = self.values[idx - 1]; - - self.len = idx - 1; + } else { + self.push_value(value); } return .{ .left = self, .middle = middle, .right = new }; } + const SearchResultTag = enum { Edge, Leaf }; + + const SearchResult = union(SearchResultTag) { + Edge: struct { leaf: *Leaf, idx: u16 }, + Leaf: struct { leaf: *Leaf, idx: u16 }, + }; + + fn find_key(self: *Leaf, key: u32) SearchResult { + std.debug.print("looking for {} in {any}\n", .{ key, self.get_values() }); + for (self.get_values(), 0..) |v, i| { + if (key < v) { + std.debug.print("decending left of {}\n", .{v}); + return .{ .Edge = .{ .leaf = self, .idx = @intCast(u16, i) } }; + } else if (key == v) { + std.debug.print("located {} at {}\n", .{ key, v }); + return .{ .Leaf = .{ .leaf = self, .idx = @intCast(u16, i) } }; + } + } + + std.debug.print("decending right of {}\n", .{self.get_values()[self.len - 1]}); + return .{ .Edge = .{ .leaf = self, .idx = self.len } }; + } + // returns null on success, or a split result which could not be merged // up because we are at the root node fn insert_value(self: *Leaf, value: u32) !?SplitResult { @@ -394,6 +446,16 @@ test "btree insert" { 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(); } test "btree new" {