changeset 10:eec91e90ede7

Delete crufty deletion code
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 08 Jul 2022 22:54:56 -0700
parents 1a2cc00f6836
children b3cd822e1983
files src/lib.rs
diffstat 1 files changed, 0 insertions(+), 352 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib.rs	Fri Jul 08 22:54:30 2022 -0700
+++ b/src/lib.rs	Fri Jul 08 22:54:56 2022 -0700
@@ -362,358 +362,6 @@
             Some((_, node, nodeentry)) => self.delete_recursive(self.root, Some(entry), None),
         }
     }
-
-    fn delete_recursive(
-        &mut self,
-        from: usize,
-        entry: Option<&T>,
-        mut entryix: Option<usize>,
-    ) -> Option<T> {
-        let mut deleted = None;
-        println!("deleting in {}", from);
-
-        if entryix.is_none() {
-            let entry = entry.unwrap();
-            // If we don't know the index of the entry to delete:
-            // First, iterate through this node's elements and delete recursively if needed.
-            for i in 0..ORDER - 1 {
-                if let Some(current) = self.get(from, i) {
-                    println!("comparing {:?}, {:?}", entry, current);
-                    match Cmp::cmp(entry, current) {
-                        Ordering::Less => {
-                            if let Some(ch) = self.get_child(from, i) {
-                                deleted = self
-                                    .delete_recursive(*ch, Some(entry), None)
-                                    .map(|e| (e, i));
-                                break;
-                            } else {
-                                continue;
-                            }
-                        }
-                        Ordering::Equal => {
-                            // found!
-                            entryix = Some(i);
-                            break;
-                        }
-                        Ordering::Greater => {
-                            if i == self.count_in(from) - 1 {
-                                if let Some(ch) = self.get_child(from, i + 1) {
-                                    // Descend into child-after-last entry
-                                    deleted = self
-                                        .delete_recursive(*ch, Some(entry), None)
-                                        .map(|e| (e, i + 1));
-                                    break;
-                                }
-                            } else {
-                                continue;
-                            }
-                        }
-                    }
-                } else {
-                    break;
-                }
-            }
-        }
-
-        // Distinguish cases:
-        // 1. Current node has entry to delete.
-        // 2. Deletion occured in some subnode. Check immediate children if rebalancing is needed.
-
-        println!("Back in {}", from);
-        println!("Found {:?} , {:?}", entryix, deleted);
-        if let Some(entryix) = entryix {
-            // 1. Current node has entry to be deleted.
-            //
-            if self.is_leaf(from) {
-                // If we're in a leaf, simple deletion is ok.
-                let d = self.get_mut(from, entryix).take();
-                for i in entryix..ORDER - 2 {
-                    *self.get_mut(from, i) = self.get_mut(from, i + 1).take();
-                }
-                return d;
-            } else {
-                // Non-leaf: need to rotate or merge.
-                let leftchild = self.get_child(from, entryix).unwrap();
-                let rightchild = self.get_child(from, entryix + 1).unwrap();
-                let leftcount = self.count_in(leftchild);
-                let rightcount = self.count_in(rightchild);
-
-                let d = self.get_mut(from, entryix).take();
-
-                // Enough entries in children.
-                if leftcount + rightcount > ORDER - 1 {
-                    let lefttoright = leftcount > rightcount;
-                    if lefttoright {
-                        // Remove last element from left node, recursively.
-                        let formerleft = self.delete_recursive(
-                            leftchild,
-                            None,
-                            Some(self.count_in(leftchild) - 1),
-                        );
-                        *self.get_mut(from, entryix) = formerleft;
-                    } else {
-                        // right to left
-                        let formerright = self.delete_recursive(rightchild, None, Some(0));
-                        *self.get_mut(from, entryix) = formerright;
-                    }
-                    return d;
-                } else {
-                    // Need to merge both children; discard entry-to-be-deleted
-                    let newnodeix = self.merge_nodes(from, entryix, /* discard= */ true);
-                    if from == self.root && self.count_in(self.root) == 0 {
-                        self.root = newnodeix;
-                    }
-                    return d;
-                }
-            }
-        } else if let Some((d, child)) = deleted {
-            // Entry was deleted in sub-operation.
-            // Check if invariants fulfilled.
-            if self.count_in(child) >= ORDER / 2 {
-                return Some(d);
-            } else {
-                // Child doesn't have enough entries. Attempt rotation or merge.
-
-                // Can rotate?
-                let leftchild;
-                let rightchild;
-                let entryix;
-                if child < ORDER - 1 {
-                    if child < self.count_in(from) {
-                        leftchild = self.get_child(from, child).unwrap();
-                        rightchild = self.get_child(from, child + 1).unwrap();
-                        entryix = child;
-                    } else {
-                        leftchild = self.get_child(from, child - 1).unwrap();
-                        rightchild = self.get_child(from, child).unwrap();
-                        entryix = child - 1;
-                    }
-                } else {
-                    // If child is right-most child.
-                    leftchild = self.get_child(from, child - 1).unwrap();
-                    rightchild = self.get_child(from, child).unwrap();
-                    entryix = child - 1;
-                }
-                let leftcount = self.count_in(leftchild);
-                let rightcount = self.count_in(rightchild);
-
-                // Enough entries in children to rotate.
-                if leftcount + rightcount + 1 > ORDER - 1 {
-                    let piv = self.get_mut(from, entryix).take();
-                    let lefttoright = leftcount > rightcount;
-                    if lefttoright {
-                        // Remove last element from left node, recursively.
-                        let formerleft = self.delete_recursive(
-                            leftchild,
-                            None,
-                            Some(self.count_in(leftchild) - 1),
-                        );
-                        self.insert_into(rightchild, piv.unwrap());
-                        *self.get_mut(from, entryix) = formerleft;
-                    } else {
-                        // right to left
-                        let formerright = self.delete_recursive(rightchild, None, Some(0));
-                        self.insert_into(leftchild, piv.unwrap());
-                        *self.get_mut(from, entryix) = formerright;
-                    }
-                } else {
-                    // Need to merge both children; do not discard pivot entry (entry between
-                    // children to be merged).
-                    let newnodeix;
-                    if child < ORDER - 1 && child < self.count_in(from) {
-                        newnodeix = self.merge_nodes(from, child, /* discard= */ false);
-                    } else {
-                        newnodeix = self.merge_nodes(from, child - 1, false);
-                    }
-                    if from == self.root && self.count_in(self.root) == 0 {
-                        self.root = newnodeix;
-                    }
-                }
-                return Some(d);
-            }
-        } else {
-            unimplemented!();
-        }
-    }
-
-    fn merge_nodes(&mut self, parent: usize, parentix: usize, discard: bool) -> usize {
-        let mut newnode = Node::new();
-        let mut count = 0;
-
-        println!("merging nodes at {} with child {}", parent, parentix);
-        // Move elements.
-        let left = self.get_child(parent, parentix).unwrap();
-        // Move left elements first.
-        for i in 0..ORDER - 1 {
-            newnode.entries[i] = self.get_mut(left, i).take();
-            newnode.children[i] = self.get_child_mut(left, i).take();
-            if newnode.entries[i].is_none() {
-                break;
-            }
-            count += 1;
-        }
-        // Copy left node's rightmost child
-        newnode.children[count+1] = self.get_child_mut(left, count+1).take();
-        // Move old pivot eleement.
-        if !discard {
-            newnode.entries[count] = self.get_mut(parent, parentix).take();
-            count += 1;
-        }
-        // Move right elements.
-        let right = *self.get_child(parent, parentix + 1);
-        println!("merge_nodes: right = {:?}", right);
-        let filled = count;
-        if let Some(right) = right {
-            for i in filled..ORDER - 1 {
-                newnode.entries[i] = self.get_mut(right, i - filled).take();
-                newnode.children[i] = self.get_child_mut(right, i-filled).take();
-                if newnode.entries[i].is_none() {
-                    break;
-                }
-                count += 1;
-            }
-            newnode.children[count] = self.get_child_mut(right, count-filled+1).take();
-        }
-
-        let newnodeix = self.v.len();
-        self.v.push(newnode);
-        *self.get_child_mut(parent, parentix) = Some(newnodeix);
-
-        // TODO!! Recycle nodes!!
-        for i in parentix..ORDER - 2 {
-            *self.get_mut(parent, i) = self.get_mut(parent, i + 1).take();
-            *self.get_child_mut(parent, i + 1) = self.get_child_mut(parent, i + 2).take();
-        }
-        newnodeix
-    }
-
-    fn rotate(&mut self, node: usize, ix: usize, lefttoright: bool) {
-        let leftchild = *self.get_child(node, ix);
-        let rightchild = *self.get_child(node, ix + 1);
-
-        if let (Some(leftchild), Some(rightchild)) = (leftchild, rightchild) {
-            let piv = self.get_mut(node, ix).take();
-            if lefttoright {
-                self.insert_into(rightchild, piv.unwrap());
-                *self.get_child_mut(rightchild, 0) = self.get_child_mut(leftchild, self.count_in(leftchild)).take();
-                // Remove last element from left node, recursively.
-                let formerleft =
-                    self.delete_recursive(leftchild, None, Some(self.count_in(leftchild) - 1));
-                *self.get_mut(node, ix) = formerleft;
-            } else {
-                // right to left
-                let formerright = self.delete_recursive(rightchild, None, Some(0));
-                self.insert_into(leftchild, piv.unwrap());
-                *self.get_mut(node, ix) = formerright;
-            }
-        } else {
-            panic!(
-                "Cannot rotate asymmetrically: {:?}",
-                (leftchild, rightchild)
-            );
-        }
-    }
-
-    fn delete_entry(&mut self, node: usize, entry: usize) -> T {
-        // Entry must exist!!
-        if self.is_leaf(node) {
-            // Shift, and return.
-            let d = self.get_mut(node, entry).take();
-            for i in entry..ORDER - 1 {
-                *self.get_mut(node, i) = self.get_mut(node, i + 1).take();
-                assert!(self.get_child(node, i).is_none());
-                if self.get(node, i).is_none() {
-                    break;
-                }
-            }
-            // TO DO: rotate or merge. Need access to parent!
-            assert!(self.get_child(node, self.count_in(node)).is_none());
-            return d.unwrap();
-        } else {
-            // Non-leaf.
-            // Remove entry;
-            // rotate left or right subtree element into place by removing it from there as well.
-            let d = self.get_mut(node, entry).take();
-            let (left, right) = (
-                self.v[node].children[entry],
-                self.v[node].children[entry + 1],
-            );
-            let (candidate, ix, need_restructure) = match (left, right) {
-                (Some(l), Some(r)) => {
-                    let (leftcount, rightcount) = (self.count_in(l), self.count_in(r));
-                    if leftcount <= rightcount {
-                        (r, 0, rightcount < ORDER / 2)
-                    } else {
-                        (l, leftcount - 1, leftcount < ORDER / 2)
-                    }
-                }
-                (Some(l), None) => (l, self.count_in(l) - 1, self.count_in(l) < ORDER / 2),
-                (None, Some(r)) => {
-                    panic!("Tree architecture fault: no left subchild but right subchild")
-                }
-                (None, None) => panic!("delete_entry in leaf node, but expected internal node"),
-            };
-
-            // Recurse into subtree.
-            *self.get_mut(node, entry) = Some(self.delete_entry(candidate, ix));
-
-            // Merge nodes if either node is too small.
-            if need_restructure {
-                // Can we rotate into place?
-                if let (Some(l), Some(r)) = (left, right) {
-                    let (leftcount, rightcount) = (self.count_in(l), self.count_in(r));
-                    if leftcount + rightcount > ORDER {
-                        // Yes!
-                        let to_move = self.get_mut(node, entry).take().unwrap();
-                        if leftcount < rightcount {
-                            self.insert_into(l, to_move);
-                            *self.get_mut(node, entry) = Some(self.delete_entry(r, 0));
-                        } else {
-                            self.insert_into(r, to_move);
-                            *self.get_mut(node, entry) = Some(self.delete_entry(l, leftcount - 1));
-                        }
-                    }
-                } else {
-                    // Need to merge two nodes.
-                    // Remove current entry and add it to a new node, together with left and right
-                    // nodes' entries.
-                    let mut newnode = Node::new();
-                    let mut count = 0;
-
-                    // Move elements.
-                    let left = self.get_child(node, entry).unwrap();
-                    // Move left elements first.
-                    for i in 0..ORDER - 1 {
-                        newnode.entries[i] = self.get_mut(left, i).take();
-                        count += 1;
-                    }
-                    // Move old pivot eleement.
-                    newnode.entries[count] = self.get_mut(node, entry).take();
-                    count += 1;
-                    // Move right elements.
-                    let right = *self.get_child(node, entry + 1);
-                    if let Some(right) = right {
-                        for i in count..ORDER - 1 {
-                            newnode.entries[i] = self.get_mut(right, i - count).take();
-                            count += 1;
-                        }
-                    }
-
-                    let newnodeix = self.v.len();
-                    self.v.push(newnode);
-                    *self.get_child_mut(node, entry) = Some(newnodeix);
-
-                    // TODO!! Recycle nodes!!
-                    for i in entry..ORDER - 2 {
-                        *self.get_mut(node, i) = self.get_mut(node, i + 1).take();
-                        *self.get_child_mut(node, i + 1) = self.get_child_mut(node, i + 2).take();
-                    }
-                }
-            }
-
-            return d.unwrap();
-        }
-    }
 }
 impl<T: std::fmt::Debug, Cmp: Compare<T>> BTree<T, Cmp> {
     fn debug_print(&self) -> String {