Skip to content

Commit

Permalink
Fix bug in remove_index for OrdMap (#141)
Browse files Browse the repository at this point in the history
* Fix bug in remove_index for OrdMap

* Remove unused is_leaf

* Reproducible test for issue #124 - hopefully.

Co-authored-by: Bodil Stokke <bodil@bodil.org>
  • Loading branch information
dsarlis and bodil committed Jul 14, 2020
1 parent 7aaf0ad commit c35a913
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions src/nodes/btree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,6 @@ impl<A> Node<A> {
self.keys.len() < MEDIAN
}

#[inline]
fn is_leaf(&self) -> bool {
self.children[0].is_none()
}

#[inline]
pub(crate) fn unit(value: A) -> Self {
Node {
Expand Down Expand Up @@ -643,26 +638,35 @@ impl<A: BTreeValue> Node<A> {
match (&self.children[index], &self.children[index + 1]) {
// If we're a leaf, just delete the entry.
(&None, &None) => RemoveAction::DeleteAt(index),
// If the left hand child has capacity, pull the predecessor up.
(&Some(ref left), _) if !left.too_small() => {
if left.is_leaf() {
RemoveAction::PullUp(left.keys.len() - 1, index, index)
} else {
// Right is empty. Attempt to steal from left if enough capacity,
// otherwise pull the predecessor up.
(&Some(ref left), &None) => {
if !left.too_small() {
RemoveAction::StealFromLeft(index + 1)
} else {
RemoveAction::PullUp(left.keys.len() - 1, index, index)
}
}
// If the right hand child has capacity, pull the successor up.
(_, &Some(ref right)) if !right.too_small() => {
if right.is_leaf() {
RemoveAction::PullUp(0, index, index + 1)
// Left is empty. Attempt to steal from right if enough capacity,
// otherwise pull the successor up.
(&None, &Some(ref right)) => {
if !right.too_small() {
RemoveAction::StealFromRight(index)
} else {
RemoveAction::PullUp(0, index, index + 1)
}
}
// Both left and right are non empty. Attempt to steal from left or
// right if enough capacity, otherwise just merge the children.
(&Some(ref left), &Some(ref right)) => {
if left.has_room() && !right.too_small() {
RemoveAction::StealFromRight(index)
} else if right.has_room() && !left.too_small() {
RemoveAction::StealFromLeft(index + 1)
} else {
RemoveAction::Merge(index)
}
}
// If neither child has capacity, we'll have to merge them.
(&Some(_), &Some(_)) => RemoveAction::Merge(index),
// If one child exists and the other doesn't, we're in a bad state.
_ => unreachable!(),
}
}
// Key is adjacent to some key in node
Expand Down

0 comments on commit c35a913

Please sign in to comment.