Skip to content

Commit

Permalink
BTreeMap: reuse NodeRef as Root, keep BoxedNode for edges only, ban U…
Browse files Browse the repository at this point in the history
…nique
  • Loading branch information
ssomers committed Nov 18, 2020
1 parent c4f836a commit 9fca57c
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 176 deletions.
4 changes: 2 additions & 2 deletions library/alloc/src/collections/btree/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl<K, V> Root<K, V> {
where
I: Iterator<Item = (K, V)>,
{
let mut cur_node = self.node_as_mut().last_leaf_edge().into_node();
let mut cur_node = self.borrow_mut().last_leaf_edge().into_node();
// Iterate through all key-value pairs, pushing them into nodes at the right level.
for (key, value) in iter {
// Try to push key-value pair into the current leaf node.
Expand Down Expand Up @@ -86,7 +86,7 @@ impl<K, V> Root<K, V> {

fn fix_right_edge(&mut self) {
// Handle underfull nodes, start from the top.
let mut cur_node = self.node_as_mut();
let mut cur_node = self.borrow_mut();
while let Internal(internal) = cur_node.force() {
// Check if right-most child is underfull.
let mut last_kv = internal.last_kv().consider_for_balancing();
Expand Down
44 changes: 22 additions & 22 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {

{
let root = out_tree.root.as_mut().unwrap(); // unwrap succeeds because we just wrapped
let mut out_node = match root.node_as_mut().force() {
let mut out_node = match root.borrow_mut().force() {
Leaf(leaf) => leaf,
Internal(_) => unreachable!(),
};
Expand Down Expand Up @@ -213,7 +213,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
// Ord` constraint, which this method lacks.
BTreeMap { root: None, length: 0 }
} else {
clone_subtree(self.root.as_ref().unwrap().node_as_ref()) // unwrap succeeds because not empty
clone_subtree(self.root.as_ref().unwrap().reborrow()) // unwrap succeeds because not empty
}
}
}
Expand All @@ -226,7 +226,7 @@ where
type Key = K;

fn get(&self, key: &Q) -> Option<&K> {
let root_node = self.root.as_ref()?.node_as_ref();
let root_node = self.root.as_ref()?.reborrow();
match search::search_tree(root_node, key) {
Found(handle) => Some(handle.into_kv().0),
GoDown(_) => None,
Expand All @@ -235,7 +235,7 @@ where

fn take(&mut self, key: &Q) -> Option<K> {
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.node_as_mut();
let root_node = map.root.as_mut()?.borrow_mut();
match search::search_tree(root_node, key) {
Found(handle) => {
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_kv().0)
Expand All @@ -246,7 +246,7 @@ where

fn replace(&mut self, key: K) -> Option<K> {
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = Self::ensure_is_owned(&mut map.root).node_as_mut();
let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut();
match search::search_tree::<marker::Mut<'_>, K, (), K>(root_node, &key) {
Found(handle) => Some(mem::replace(handle.into_key_mut(), key)),
GoDown(handle) => {
Expand Down Expand Up @@ -522,7 +522,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
K: Borrow<Q>,
Q: Ord,
{
let root_node = self.root.as_ref()?.node_as_ref();
let root_node = self.root.as_ref()?.reborrow();
match search::search_tree(root_node, key) {
Found(handle) => Some(handle.into_kv().1),
GoDown(_) => None,
Expand Down Expand Up @@ -550,7 +550,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
K: Borrow<Q>,
Q: Ord,
{
let root_node = self.root.as_ref()?.node_as_ref();
let root_node = self.root.as_ref()?.reborrow();
match search::search_tree(root_node, k) {
Found(handle) => Some(handle.into_kv()),
GoDown(_) => None,
Expand All @@ -576,7 +576,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
#[unstable(feature = "map_first_last", issue = "62924")]
pub fn first_key_value(&self) -> Option<(&K, &V)> {
let root_node = self.root.as_ref()?.node_as_ref();
let root_node = self.root.as_ref()?.reborrow();
root_node.first_leaf_edge().right_kv().ok().map(Handle::into_kv)
}

Expand All @@ -603,7 +603,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
#[unstable(feature = "map_first_last", issue = "62924")]
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.node_as_mut();
let root_node = map.root.as_mut()?.borrow_mut();
let kv = root_node.first_leaf_edge().right_kv().ok()?;
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
}
Expand Down Expand Up @@ -650,7 +650,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
#[unstable(feature = "map_first_last", issue = "62924")]
pub fn last_key_value(&self) -> Option<(&K, &V)> {
let root_node = self.root.as_ref()?.node_as_ref();
let root_node = self.root.as_ref()?.reborrow();
root_node.last_leaf_edge().left_kv().ok().map(Handle::into_kv)
}

Expand All @@ -677,7 +677,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
#[unstable(feature = "map_first_last", issue = "62924")]
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.node_as_mut();
let root_node = map.root.as_mut()?.borrow_mut();
let kv = root_node.last_leaf_edge().left_kv().ok()?;
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
}
Expand Down Expand Up @@ -758,7 +758,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
K: Borrow<Q>,
Q: Ord,
{
let root_node = self.root.as_mut()?.node_as_mut();
let root_node = self.root.as_mut()?.borrow_mut();
match search::search_tree(root_node, key) {
Found(handle) => Some(handle.into_val_mut()),
GoDown(_) => None,
Expand Down Expand Up @@ -854,7 +854,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
Q: Ord,
{
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.node_as_mut();
let root_node = map.root.as_mut()?.borrow_mut();
match search::search_tree(root_node, key) {
Found(handle) => {
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_entry())
Expand Down Expand Up @@ -971,7 +971,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
R: RangeBounds<T>,
{
if let Some(root) = &self.root {
let (f, b) = root.node_as_ref().range_search(range);
let (f, b) = root.reborrow().range_search(range);

Range { front: Some(f), back: Some(b) }
} else {
Expand Down Expand Up @@ -1017,7 +1017,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
R: RangeBounds<T>,
{
if let Some(root) = &mut self.root {
let (f, b) = root.node_as_valmut().range_search(range);
let (f, b) = root.borrow_valmut().range_search(range);

RangeMut { front: Some(f), back: Some(b), _marker: PhantomData }
} else {
Expand Down Expand Up @@ -1047,7 +1047,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
// FIXME(@porglezomp) Avoid allocating if we don't insert
let (map, dormant_map) = DormantMutRef::new(self);
let root_node = Self::ensure_is_owned(&mut map.root).node_as_mut();
let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut();
match search::search_tree(root_node, &key) {
Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }),
GoDown(handle) => {
Expand Down Expand Up @@ -1103,10 +1103,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
left_root.split_off(right_root, key);

if left_root.height() < right_root.height() {
self.length = left_root.node_as_ref().calc_length();
self.length = left_root.reborrow().calc_length();
right.length = total_num - self.len();
} else {
right.length = right_root.node_as_ref().calc_length();
right.length = right_root.reborrow().calc_length();
self.length = total_num - right.len();
}

Expand Down Expand Up @@ -1154,7 +1154,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
if let Some(root) = self.root.as_mut() {
let (root, dormant_root) = DormantMutRef::new(root);
let front = root.node_as_mut().first_leaf_edge();
let front = root.borrow_mut().first_leaf_edge();
DrainFilterInner {
length: &mut self.length,
dormant_root: Some(dormant_root),
Expand Down Expand Up @@ -1361,7 +1361,7 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
fn into_iter(self) -> IntoIter<K, V> {
let mut me = ManuallyDrop::new(self);
if let Some(root) = me.root.take() {
let (f, b) = root.into_ref().full_range();
let (f, b) = root.full_range();

IntoIter { front: Some(f), back: Some(b), length: me.length }
} else {
Expand Down Expand Up @@ -2007,7 +2007,7 @@ impl<K, V> BTreeMap<K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter(&self) -> Iter<'_, K, V> {
if let Some(root) = &self.root {
let (f, b) = root.node_as_ref().full_range();
let (f, b) = root.reborrow().full_range();

Iter { range: Range { front: Some(f), back: Some(b) }, length: self.length }
} else {
Expand Down Expand Up @@ -2039,7 +2039,7 @@ impl<K, V> BTreeMap<K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
if let Some(root) = &mut self.root {
let (f, b) = root.node_as_valmut().full_range();
let (f, b) = root.borrow_valmut().full_range();

IterMut {
range: RangeMut { front: Some(f), back: Some(b), _marker: PhantomData },
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/btree/map/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
// Safety: We have consumed self.handle and the reference returned.
let map = unsafe { self.dormant_map.awaken() };
let root = map.root.as_mut().unwrap();
root.push_internal_level().push(ins.k, ins.v, ins.right);
root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right);
map.length += 1;
val_ptr
}
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/collections/btree/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<K, V> BTreeMap<K, V> {
// Panics if the map (or the code navigating it) is corrupted.
fn check_invariants(&self) {
if let Some(root) = &self.root {
let root_node = root.node_as_ref();
let root_node = root.reborrow();

// Check the back pointers top-down, before we attempt to rely on
// more serious navigation code.
Expand Down Expand Up @@ -92,7 +92,7 @@ impl<K, V> BTreeMap<K, V> {
K: Debug,
{
if let Some(root) = self.root.as_ref() {
root.node_as_ref().dump_keys()
root.reborrow().dump_keys()
} else {
String::from("not yet allocated")
}
Expand Down
Loading

0 comments on commit 9fca57c

Please sign in to comment.