let mut out_tree = clone_subtree(internal.first_edge().descend());
{
- let out_root = BTreeMap::ensure_is_owned(&mut out_tree.root);
+ let out_root = out_tree.root.as_mut().unwrap();
let mut out_node = out_root.push_internal_level();
let mut in_edge = internal.first_edge();
while let Ok(kv) = in_edge.right_kv() {
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).borrow_mut();
+ let root_node = map.root.get_or_insert_with(Root::new).borrow_mut();
match root_node.search_tree::<K>(&key) {
Found(mut kv) => Some(mem::replace(kv.key_mut(), key)),
GoDown(handle) => {
- VacantEntry { key, handle, dormant_map, _marker: PhantomData }.insert(());
+ VacantEntry { key, handle: Some(handle), dormant_map, _marker: PhantomData }
+ .insert(());
None
}
}
let self_iter = mem::take(self).into_iter();
let other_iter = mem::take(other).into_iter();
- let root = BTreeMap::ensure_is_owned(&mut self.root);
+ let root = self.root.get_or_insert_with(Root::new);
root.append_from_sorted_iters(self_iter, other_iter, &mut self.length)
}
where
K: Ord,
{
- // 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).borrow_mut();
- match root_node.search_tree(&key) {
- Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }),
- GoDown(handle) => {
- Vacant(VacantEntry { key, handle, dormant_map, _marker: PhantomData })
- }
+ match map.root {
+ None => Vacant(VacantEntry { key, handle: None, dormant_map, _marker: PhantomData }),
+ Some(ref mut root) => match root.borrow_mut().search_tree(&key) {
+ Found(handle) => {
+ Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData })
+ }
+ GoDown(handle) => Vacant(VacantEntry {
+ key,
+ handle: Some(handle),
+ dormant_map,
+ _marker: PhantomData,
+ }),
+ },
}
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
-
- /// If the root node is the empty (non-allocated) root node, allocate our
- /// own node. Is an associated function to avoid borrowing the entire BTreeMap.
- fn ensure_is_owned(root: &mut Option<Root<K, V>>) -> &mut Root<K, V> {
- root.get_or_insert_with(Root::new)
- }
}
#[cfg(test)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> {
pub(super) key: K,
- pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>,
+ /// `None` for a (empty) map without root
+ pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>,
// Be invariant in `K` and `V`
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(self, value: V) -> &'a mut V {
- let out_ptr = match self.handle.insert_recursing(self.key, value) {
- (None, val_ptr) => {
- // SAFETY: We have consumed self.handle and the handle returned.
- let map = unsafe { self.dormant_map.awaken() };
- map.length += 1;
- val_ptr
- }
- (Some(ins), val_ptr) => {
- drop(ins.left);
+ let out_ptr = match self.handle {
+ None => {
// 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.kv.0, ins.kv.1, ins.right);
- map.length += 1;
+ let mut root = NodeRef::new_leaf();
+ let val_ptr = root.borrow_mut().push(self.key, value) as *mut V;
+ map.root = Some(root.forget_type());
+ map.length = 1;
val_ptr
}
+ Some(handle) => match handle.insert_recursing(self.key, value) {
+ (None, val_ptr) => {
+ // SAFETY: We have consumed self.handle and the handle returned.
+ let map = unsafe { self.dormant_map.awaken() };
+ map.length += 1;
+ val_ptr
+ }
+ (Some(ins), val_ptr) => {
+ drop(ins.left);
+ // 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.kv.0, ins.kv.1, ins.right);
+ map.length += 1;
+ val_ptr
+ }
+ },
};
// Now that we have finished growing the tree using borrowed references,
// dereference the pointer to a part of it, that we picked up along the way.
K: Ord,
{
let iter = mem::take(self).into_iter();
- let root = BTreeMap::ensure_is_owned(&mut self.root);
- root.bulk_push(iter, &mut self.length);
+ if !iter.is_empty() {
+ self.root.insert(Root::new()).bulk_push(iter, &mut self.length);
+ }
}
}
fn empty() {
let mut map: BTreeMap<i32, i32> = BTreeMap::new();
map.drain_filter(|_, _| unreachable!("there's nothing to decide on"));
- assert!(map.is_empty());
+ assert_eq!(map.height(), None);
map.check();
}
assert_eq!(map.len(), len);
map.clear();
map.check();
- assert!(map.is_empty());
+ assert_eq!(map.height(), None);
}
}
let mut a = BTreeMap::new();
let key = "hello there";
let value = "value goes here";
- assert!(a.is_empty());
+ assert_eq!(a.height(), None);
a.insert(key, value);
assert_eq!(a.len(), 1);
assert_eq!(a[key], value);
let key = "hello there";
let value = "value goes here";
- assert!(a.is_empty());
+ assert_eq!(a.height(), None);
match a.entry(key) {
- Occupied(_) => panic!(),
+ Occupied(_) => unreachable!(),
Vacant(e) => {
assert_eq!(key, *e.key());
e.insert(value);
a.check();
}
+#[test]
+fn test_vacant_entry_no_insert() {
+ let mut a = BTreeMap::<&str, ()>::new();
+ let key = "hello there";
+
+ // Non-allocated
+ assert_eq!(a.height(), None);
+ match a.entry(key) {
+ Occupied(_) => unreachable!(),
+ Vacant(e) => assert_eq!(key, *e.key()),
+ }
+ // Ensures the tree has no root.
+ assert_eq!(a.height(), None);
+ a.check();
+
+ // Allocated but still empty
+ a.insert(key, ());
+ a.remove(&key);
+ assert_eq!(a.height(), Some(0));
+ assert!(a.is_empty());
+ match a.entry(key) {
+ Occupied(_) => unreachable!(),
+ Vacant(e) => assert_eq!(key, *e.key()),
+ }
+ // Ensures the allocated root is not changed.
+ assert_eq!(a.height(), Some(0));
+ assert!(a.is_empty());
+ a.check();
+}
+
#[test]
fn test_first_last_entry() {
let mut a = BTreeMap::new();
unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {}
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
- fn new_leaf() -> Self {
+ pub fn new_leaf() -> Self {
Self::from_new_leaf(LeafNode::new())
}
}
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
- /// Adds a key-value pair to the end of the node.
- pub fn push(&mut self, key: K, val: V) {
+ /// Adds a key-value pair to the end of the node, and returns
+ /// the mutable reference of the inserted value.
+ pub fn push(&mut self, key: K, val: V) -> &mut V {
let len = self.len_mut();
let idx = usize::from(*len);
assert!(idx < CAPACITY);
*len += 1;
unsafe {
self.key_area_mut(idx).write(key);
- self.val_area_mut(idx).write(val);
+ self.val_area_mut(idx).write(val)
}
}
}