ok?
This commit is contained in:
parent
d1fbb9360b
commit
d2f8b244ad
1 changed files with 74 additions and 8 deletions
82
src/btree.rs
82
src/btree.rs
|
|
@ -195,10 +195,8 @@ impl BTree {
|
||||||
parent: Option<(Node, usize)>,
|
parent: Option<(Node, usize)>,
|
||||||
input: Record,
|
input: Record,
|
||||||
) -> Option<Vec<(Node, usize)>> {
|
) -> Option<Vec<(Node, usize)>> {
|
||||||
let parent_idx = parent?.1;
|
let (parent, parent_idx) = parent?;
|
||||||
let parent = parent?.0;
|
let (node, node_idx) = node;
|
||||||
let node_idx = node.1;
|
|
||||||
let node = node.0;
|
|
||||||
|
|
||||||
let node_idx_in_parent = parent
|
let node_idx_in_parent = parent
|
||||||
.children
|
.children
|
||||||
|
|
@ -243,6 +241,76 @@ impl BTree {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_node(
|
||||||
|
node_tuple: (Node, usize),
|
||||||
|
parent: Option<(Node, usize)>,
|
||||||
|
input: Record,
|
||||||
|
next_node_idx: usize,
|
||||||
|
) -> Vec<(Node, usize)> {
|
||||||
|
let (mut node, node_idx) = node_tuple;
|
||||||
|
|
||||||
|
// 1. Collect all keys (node + input)
|
||||||
|
let mut all_keys: Vec<Record> = (0..node.num_keys).filter_map(|i| node.keys[i]).collect();
|
||||||
|
all_keys.push(input);
|
||||||
|
all_keys.sort_by_key(|r| r.key);
|
||||||
|
|
||||||
|
// 2. Determine middle key
|
||||||
|
let mid_idx = all_keys.len() / 2;
|
||||||
|
let middle_key = all_keys[mid_idx];
|
||||||
|
|
||||||
|
// 3. Update left node with keys before middle
|
||||||
|
node.keys.fill(None);
|
||||||
|
for i in 0..mid_idx {
|
||||||
|
node.keys[i] = Some(all_keys[i]);
|
||||||
|
}
|
||||||
|
node.num_keys = mid_idx;
|
||||||
|
|
||||||
|
// 4. Create new right node
|
||||||
|
let mut right = Node::new(node.is_leaf);
|
||||||
|
for i in 0..(all_keys.len() - mid_idx - 1) {
|
||||||
|
right.keys[i] = Some(all_keys[mid_idx + 1 + i]);
|
||||||
|
}
|
||||||
|
right.num_keys = all_keys.len() - mid_idx - 1;
|
||||||
|
let right_idx = next_node_idx;
|
||||||
|
|
||||||
|
let mut result = vec![(node, node_idx), (right, right_idx)];
|
||||||
|
|
||||||
|
// 5. Update or create parent
|
||||||
|
match parent {
|
||||||
|
Some((mut par_node, par_idx)) => {
|
||||||
|
let mut insert_pos = 0;
|
||||||
|
while insert_pos < par_node.num_keys
|
||||||
|
&& par_node.keys[insert_pos].unwrap().key < middle_key.key
|
||||||
|
{
|
||||||
|
insert_pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in (insert_pos..par_node.num_keys).rev() {
|
||||||
|
par_node.keys[i + 1] = par_node.keys[i];
|
||||||
|
par_node.children[i + 2] = par_node.children[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
par_node.keys[insert_pos] = Some(middle_key);
|
||||||
|
par_node.children[insert_pos + 1] = Some(right_idx);
|
||||||
|
par_node.num_keys += 1;
|
||||||
|
|
||||||
|
result.push((par_node, par_idx));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut root = Node::new(false);
|
||||||
|
root.keys[0] = Some(middle_key);
|
||||||
|
root.num_keys = 1;
|
||||||
|
root.children[0] = Some(node_idx);
|
||||||
|
root.children[1] = Some(right_idx);
|
||||||
|
|
||||||
|
// Assign root index — usually 0 if creating from empty tree
|
||||||
|
result.push((root, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, input: Record) {
|
pub fn insert(&mut self, input: Record) {
|
||||||
use FindResult::*;
|
use FindResult::*;
|
||||||
|
|
||||||
|
|
@ -270,9 +338,6 @@ impl BTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
NotFound { node, parent } => {
|
NotFound { node, parent } => {
|
||||||
// Main insertion flow
|
|
||||||
let key = input;
|
|
||||||
|
|
||||||
// 1) Try normal insertion
|
// 1) Try normal insertion
|
||||||
if let Some(updated_node) = BTree::try_insert_without_split(node.0, input) {
|
if let Some(updated_node) = BTree::try_insert_without_split(node.0, input) {
|
||||||
self.storage.write_node(node.1, &updated_node);
|
self.storage.write_node(node.1, &updated_node);
|
||||||
|
|
@ -288,7 +353,8 @@ impl BTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Must split and possibly recurse upward
|
// 3) Must split and possibly recurse upward
|
||||||
let nodes_to_write = BTree::split(node.0, parent, input);
|
let nodes_to_write =
|
||||||
|
BTree::split_node(node, parent, input, self.storage.num_nodes());
|
||||||
for (n, idx) in nodes_to_write {
|
for (n, idx) in nodes_to_write {
|
||||||
self.storage.write_node(idx, &n);
|
self.storage.write_node(idx, &n);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue