changeset 1:04b6ed18abf3

Better splitting
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 04 Jul 2022 18:14:18 -0700
parents e342ded1647e
children df21e58157f3
files src/lib.rs
diffstat 1 files changed, 46 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib.rs	Mon Jul 04 16:59:06 2022 -0700
+++ b/src/lib.rs	Mon Jul 04 18:14:18 2022 -0700
@@ -1,7 +1,7 @@
+use ptree::TreeBuilder;
 use std::cmp::Ordering;
-use ptree::TreeBuilder;
 
-const ORDER: usize = 3;
+const ORDER: usize = 5;
 
 #[derive(Debug)]
 struct Node<T> {
@@ -26,7 +26,7 @@
     root: usize,
 }
 
-impl<T: Ord> BTree<T> {
+impl<T: std::fmt::Debug + Ord> BTree<T> {
     fn new(initial_capacity: usize) -> BTree<T> {
         BTree {
             v: Vec::with_capacity(initial_capacity),
@@ -120,15 +120,17 @@
                 return true;
             } else {
                 // We have to split.
-                self.split(node, value, i);
-                return true;
+                //self.split(node, Some(value), i);
+                let new = self.split(node, None, 0);
+                node = new;
+                continue;
             }
         }
     }
 
     /// Split node `node` at `loc`, moving all values at `loc` and higher to the right node,
     /// inserting `value` into a new parent node.
-    fn split(&mut self, node: usize, value: T, loc: usize) -> usize {
+    fn split(&mut self, node: usize, value: Option<T>, loc: usize) -> usize {
         let leftix = node;
         let rightix = self.v.len();
         let topix = self.v.len() + 1;
@@ -136,19 +138,36 @@
         let mut right = Node::new(Some(topix));
         let mut top = Node::new(self.v[node].parent);
 
-        // Put pivot entry into top node.
-        top.entries[0] = Some(value);
+        // TODO: We create a top node. In reality, the pivot value is to be inserted into the
+        // existing parent node.
+        if value.is_some() {
+            // Put pivot entry into top node.
+            top.entries[0] = value;
+
+            // Copy greater elements to right node.
+            for i in loc..ORDER - 1 {
+                right.entries[i - loc] = self.get_mut(node, i).take();
+            }
 
-        // Copy greater elements to right node.
-        for i in loc..ORDER - 1 {
-            right.entries[i - loc] = self.get_mut(node, i).take();
+            // left
+            top.children[0] = Some(leftix);
+            // right
+            top.children[1] = Some(rightix);
+        } else {
+            // Split without inserting value.
+            let pivotix = (ORDER-1) / 2;
+            let pivot = self.get_mut(node, pivotix).take();
+
+            top.entries[0] = pivot;
+            // Copy greater elements to right node.
+            for i in pivotix..ORDER - 2 {
+                right.entries[i - pivotix] = self.get_mut(node, i+1).take();
+                println!("Inserting {:?} at {}", right.entries[i-pivotix], i-pivotix);
+            }
+
+            top.children[0] = Some(leftix);
+            top.children[1] = Some(rightix);
         }
-
-        // left
-        top.children[0] = Some(leftix);
-        // right
-        top.children[1] = Some(rightix);
-
         // Update parent.
         {
             if let Some(parentix) = self.v[leftix].parent {
@@ -182,7 +201,7 @@
     }
     fn print_subtree(&self, tb: &mut TreeBuilder, node: usize) {
         let node = &self.v[node];
-        for i in 0..ORDER-1 {
+        for i in 0..ORDER - 1 {
             if let Some(ch) = node.children[i] {
                 self.print_subtree(tb.begin_child(format!("<{}>", ch)), ch);
                 tb.end_child();
@@ -199,21 +218,16 @@
     fn basic_test() {
         let mut bt = BTree::<i32>::new(16);
 
-        bt.insert(42);
-        bt.insert(52);
-        bt.insert(32);
-        bt.insert(22);
-        bt.insert(12);
-        bt.insert(62);
-        bt.insert(3);
-        bt.insert(1);
-        bt.insert(2);
-        bt.insert(4);
+        let ns = &[2,4,6,8,10,12,14,1,16,18,20,7,22,24,26,28,30];
 
-        println!("{}", bt.debug_print());
-        println!("root: {}", bt.root);
-        for (i, e) in bt.v.iter().enumerate() {
-            println!("{} {:?}", i, e);
+        for n in ns {
+            bt.insert(*n);
+            println!("Inserting {}", n);
+            println!("root: {}", bt.root);
+            println!("{}", bt.debug_print());
         }
+            for (i, e) in bt.v.iter().enumerate() {
+                println!("{} {:?}", i, e);
+            }
     }
 }