BTreeMap: more expressive local variables in merge
This commit is contained in:
parent
12813159a9
commit
94fd1d325c
@ -1352,66 +1352,65 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
|
|||||||
///
|
///
|
||||||
/// Panics unless we `.can_merge()`.
|
/// Panics unless we `.can_merge()`.
|
||||||
pub fn merge(
|
pub fn merge(
|
||||||
mut self,
|
self,
|
||||||
track_edge_idx: Option<LeftOrRight<usize>>,
|
track_edge_idx: Option<LeftOrRight<usize>>,
|
||||||
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
|
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
|
||||||
|
let Handle { node: mut parent_node, idx: parent_idx, _marker } = self.parent;
|
||||||
|
let old_parent_len = parent_node.len();
|
||||||
let mut left_node = self.left_child;
|
let mut left_node = self.left_child;
|
||||||
let left_len = left_node.len();
|
let old_left_len = left_node.len();
|
||||||
let right_node = self.right_child;
|
let right_node = self.right_child;
|
||||||
let right_len = right_node.len();
|
let right_len = right_node.len();
|
||||||
|
let new_left_len = old_left_len + 1 + right_len;
|
||||||
|
|
||||||
assert!(left_len + right_len < CAPACITY);
|
assert!(new_left_len <= CAPACITY);
|
||||||
assert!(match track_edge_idx {
|
assert!(match track_edge_idx {
|
||||||
None => true,
|
None => true,
|
||||||
Some(LeftOrRight::Left(idx)) => idx <= left_len,
|
Some(LeftOrRight::Left(idx)) => idx <= old_left_len,
|
||||||
Some(LeftOrRight::Right(idx)) => idx <= right_len,
|
Some(LeftOrRight::Right(idx)) => idx <= right_len,
|
||||||
});
|
});
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*left_node.reborrow_mut().into_len_mut() += right_len as u16 + 1;
|
*left_node.reborrow_mut().into_len_mut() = new_left_len as u16;
|
||||||
|
|
||||||
let parent_key = slice_remove(
|
let parent_key =
|
||||||
self.parent.node.reborrow_mut().into_key_area_slice(),
|
slice_remove(parent_node.reborrow_mut().into_key_area_slice(), parent_idx);
|
||||||
self.parent.idx,
|
left_node.reborrow_mut().into_key_area_mut_at(old_left_len).write(parent_key);
|
||||||
);
|
|
||||||
left_node.reborrow_mut().into_key_area_mut_at(left_len).write(parent_key);
|
|
||||||
ptr::copy_nonoverlapping(
|
ptr::copy_nonoverlapping(
|
||||||
right_node.reborrow().key_area().as_ptr(),
|
right_node.reborrow().key_area().as_ptr(),
|
||||||
left_node.reborrow_mut().into_key_area_slice().as_mut_ptr().add(left_len + 1),
|
left_node.reborrow_mut().into_key_area_slice().as_mut_ptr().add(old_left_len + 1),
|
||||||
right_len,
|
right_len,
|
||||||
);
|
);
|
||||||
|
|
||||||
let parent_val = slice_remove(
|
let parent_val =
|
||||||
self.parent.node.reborrow_mut().into_val_area_slice(),
|
slice_remove(parent_node.reborrow_mut().into_val_area_slice(), parent_idx);
|
||||||
self.parent.idx,
|
left_node.reborrow_mut().into_val_area_mut_at(old_left_len).write(parent_val);
|
||||||
);
|
|
||||||
left_node.reborrow_mut().into_val_area_mut_at(left_len).write(parent_val);
|
|
||||||
ptr::copy_nonoverlapping(
|
ptr::copy_nonoverlapping(
|
||||||
right_node.reborrow().val_area().as_ptr(),
|
right_node.reborrow().val_area().as_ptr(),
|
||||||
left_node.reborrow_mut().into_val_area_slice().as_mut_ptr().add(left_len + 1),
|
left_node.reborrow_mut().into_val_area_slice().as_mut_ptr().add(old_left_len + 1),
|
||||||
right_len,
|
right_len,
|
||||||
);
|
);
|
||||||
|
|
||||||
slice_remove(
|
slice_remove(&mut parent_node.reborrow_mut().into_edge_area_slice(), parent_idx + 1);
|
||||||
&mut self.parent.node.reborrow_mut().into_edge_area_slice(),
|
parent_node.correct_childrens_parent_links(parent_idx + 1..old_parent_len);
|
||||||
self.parent.idx + 1,
|
*parent_node.reborrow_mut().into_len_mut() -= 1;
|
||||||
);
|
|
||||||
let parent_old_len = self.parent.node.len();
|
|
||||||
self.parent.node.correct_childrens_parent_links(self.parent.idx + 1..parent_old_len);
|
|
||||||
*self.parent.node.reborrow_mut().into_len_mut() -= 1;
|
|
||||||
|
|
||||||
if self.parent.node.height > 1 {
|
if parent_node.height > 1 {
|
||||||
// SAFETY: the height of the nodes being merged is one below the height
|
// SAFETY: the height of the nodes being merged is one below the height
|
||||||
// of the node of this edge, thus above zero, so they are internal.
|
// of the node of this edge, thus above zero, so they are internal.
|
||||||
let mut left_node = left_node.reborrow_mut().cast_to_internal_unchecked();
|
let mut left_node = left_node.reborrow_mut().cast_to_internal_unchecked();
|
||||||
let right_node = right_node.cast_to_internal_unchecked();
|
let right_node = right_node.cast_to_internal_unchecked();
|
||||||
ptr::copy_nonoverlapping(
|
ptr::copy_nonoverlapping(
|
||||||
right_node.reborrow().edge_area().as_ptr(),
|
right_node.reborrow().edge_area().as_ptr(),
|
||||||
left_node.reborrow_mut().into_edge_area_slice().as_mut_ptr().add(left_len + 1),
|
left_node
|
||||||
|
.reborrow_mut()
|
||||||
|
.into_edge_area_slice()
|
||||||
|
.as_mut_ptr()
|
||||||
|
.add(old_left_len + 1),
|
||||||
right_len + 1,
|
right_len + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
left_node.correct_childrens_parent_links(left_len + 1..=left_len + 1 + right_len);
|
left_node.correct_childrens_parent_links(old_left_len + 1..new_left_len + 1);
|
||||||
|
|
||||||
Global.deallocate(right_node.node.cast(), Layout::new::<InternalNode<K, V>>());
|
Global.deallocate(right_node.node.cast(), Layout::new::<InternalNode<K, V>>());
|
||||||
} else {
|
} else {
|
||||||
@ -1421,7 +1420,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
|
|||||||
let new_idx = match track_edge_idx {
|
let new_idx = match track_edge_idx {
|
||||||
None => 0,
|
None => 0,
|
||||||
Some(LeftOrRight::Left(idx)) => idx,
|
Some(LeftOrRight::Left(idx)) => idx,
|
||||||
Some(LeftOrRight::Right(idx)) => left_len + 1 + idx,
|
Some(LeftOrRight::Right(idx)) => old_left_len + 1 + idx,
|
||||||
};
|
};
|
||||||
Handle::new_edge(left_node, new_idx)
|
Handle::new_edge(left_node, new_idx)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user