mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 19:17:43 +00:00
Auto merge of #78104 - ssomers:btree_root_redux, r=Mark-Simulacrum
BTreeMap: replace Root with NodeRef<Owned, ...> `NodeRef<marker::Owned, …>` already exists as a representation of root nodes, and it makes more sense to alias `Root` to that than to reuse the space-efficient `BoxedNode` that is oblivious to height, where height is required. r? `@Mark-Simulacrum`
This commit is contained in:
commit
593fe977a7
@ -34,7 +34,7 @@ impl<K, V> Root<K, V> {
|
|||||||
where
|
where
|
||||||
I: Iterator<Item = (K, V)>,
|
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.
|
// Iterate through all key-value pairs, pushing them into nodes at the right level.
|
||||||
for (key, value) in iter {
|
for (key, value) in iter {
|
||||||
// Try to push key-value pair into the current leaf node.
|
// Try to push key-value pair into the current leaf node.
|
||||||
@ -86,7 +86,7 @@ impl<K, V> Root<K, V> {
|
|||||||
|
|
||||||
fn fix_right_edge(&mut self) {
|
fn fix_right_edge(&mut self) {
|
||||||
// Handle underfull nodes, start from the top.
|
// 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() {
|
while let Internal(internal) = cur_node.force() {
|
||||||
// Check if right-most child is underfull.
|
// Check if right-most child is underfull.
|
||||||
let mut last_kv = internal.last_kv().consider_for_balancing();
|
let mut last_kv = internal.last_kv().consider_for_balancing();
|
||||||
|
@ -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 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,
|
Leaf(leaf) => leaf,
|
||||||
Internal(_) => unreachable!(),
|
Internal(_) => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -213,7 +213,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
|
|||||||
// Ord` constraint, which this method lacks.
|
// Ord` constraint, which this method lacks.
|
||||||
BTreeMap { root: None, length: 0 }
|
BTreeMap { root: None, length: 0 }
|
||||||
} else {
|
} 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ where
|
|||||||
type Key = K;
|
type Key = K;
|
||||||
|
|
||||||
fn get(&self, key: &Q) -> Option<&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) {
|
match search::search_tree(root_node, key) {
|
||||||
Found(handle) => Some(handle.into_kv().0),
|
Found(handle) => Some(handle.into_kv().0),
|
||||||
GoDown(_) => None,
|
GoDown(_) => None,
|
||||||
@ -235,7 +235,7 @@ where
|
|||||||
|
|
||||||
fn take(&mut self, key: &Q) -> Option<K> {
|
fn take(&mut self, key: &Q) -> Option<K> {
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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) {
|
match search::search_tree(root_node, key) {
|
||||||
Found(handle) => {
|
Found(handle) => {
|
||||||
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_kv().0)
|
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_kv().0)
|
||||||
@ -246,7 +246,7 @@ where
|
|||||||
|
|
||||||
fn replace(&mut self, key: K) -> Option<K> {
|
fn replace(&mut self, key: K) -> Option<K> {
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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) {
|
match search::search_tree::<marker::Mut<'_>, K, (), K>(root_node, &key) {
|
||||||
Found(handle) => Some(mem::replace(handle.into_key_mut(), key)),
|
Found(handle) => Some(mem::replace(handle.into_key_mut(), key)),
|
||||||
GoDown(handle) => {
|
GoDown(handle) => {
|
||||||
@ -522,7 +522,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
K: Borrow<Q>,
|
K: Borrow<Q>,
|
||||||
Q: Ord,
|
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) {
|
match search::search_tree(root_node, key) {
|
||||||
Found(handle) => Some(handle.into_kv().1),
|
Found(handle) => Some(handle.into_kv().1),
|
||||||
GoDown(_) => None,
|
GoDown(_) => None,
|
||||||
@ -550,7 +550,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
K: Borrow<Q>,
|
K: Borrow<Q>,
|
||||||
Q: Ord,
|
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) {
|
match search::search_tree(root_node, k) {
|
||||||
Found(handle) => Some(handle.into_kv()),
|
Found(handle) => Some(handle.into_kv()),
|
||||||
GoDown(_) => None,
|
GoDown(_) => None,
|
||||||
@ -576,7 +576,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "map_first_last", issue = "62924")]
|
#[unstable(feature = "map_first_last", issue = "62924")]
|
||||||
pub fn first_key_value(&self) -> Option<(&K, &V)> {
|
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)
|
root_node.first_leaf_edge().right_kv().ok().map(Handle::into_kv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +603,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
#[unstable(feature = "map_first_last", issue = "62924")]
|
#[unstable(feature = "map_first_last", issue = "62924")]
|
||||||
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
|
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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()?;
|
let kv = root_node.first_leaf_edge().right_kv().ok()?;
|
||||||
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
|
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
|
||||||
}
|
}
|
||||||
@ -650,7 +650,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "map_first_last", issue = "62924")]
|
#[unstable(feature = "map_first_last", issue = "62924")]
|
||||||
pub fn last_key_value(&self) -> Option<(&K, &V)> {
|
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)
|
root_node.last_leaf_edge().left_kv().ok().map(Handle::into_kv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +677,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
#[unstable(feature = "map_first_last", issue = "62924")]
|
#[unstable(feature = "map_first_last", issue = "62924")]
|
||||||
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
|
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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()?;
|
let kv = root_node.last_leaf_edge().left_kv().ok()?;
|
||||||
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
|
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData })
|
||||||
}
|
}
|
||||||
@ -758,7 +758,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
K: Borrow<Q>,
|
K: Borrow<Q>,
|
||||||
Q: Ord,
|
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) {
|
match search::search_tree(root_node, key) {
|
||||||
Found(handle) => Some(handle.into_val_mut()),
|
Found(handle) => Some(handle.into_val_mut()),
|
||||||
GoDown(_) => None,
|
GoDown(_) => None,
|
||||||
@ -854,7 +854,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
Q: Ord,
|
Q: Ord,
|
||||||
{
|
{
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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) {
|
match search::search_tree(root_node, key) {
|
||||||
Found(handle) => {
|
Found(handle) => {
|
||||||
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_entry())
|
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_entry())
|
||||||
@ -971,7 +971,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
R: RangeBounds<T>,
|
R: RangeBounds<T>,
|
||||||
{
|
{
|
||||||
if let Some(root) = &self.root {
|
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) }
|
Range { front: Some(f), back: Some(b) }
|
||||||
} else {
|
} else {
|
||||||
@ -1017,7 +1017,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
R: RangeBounds<T>,
|
R: RangeBounds<T>,
|
||||||
{
|
{
|
||||||
if let Some(root) = &mut self.root {
|
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 }
|
RangeMut { front: Some(f), back: Some(b), _marker: PhantomData }
|
||||||
} else {
|
} else {
|
||||||
@ -1047,7 +1047,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
|
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
|
||||||
// FIXME(@porglezomp) Avoid allocating if we don't insert
|
// FIXME(@porglezomp) Avoid allocating if we don't insert
|
||||||
let (map, dormant_map) = DormantMutRef::new(self);
|
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) {
|
match search::search_tree(root_node, &key) {
|
||||||
Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }),
|
Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }),
|
||||||
GoDown(handle) => {
|
GoDown(handle) => {
|
||||||
@ -1103,10 +1103,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
left_root.split_off(right_root, key);
|
left_root.split_off(right_root, key);
|
||||||
|
|
||||||
if left_root.height() < right_root.height() {
|
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();
|
right.length = total_num - self.len();
|
||||||
} else {
|
} else {
|
||||||
right.length = right_root.node_as_ref().calc_length();
|
right.length = right_root.reborrow().calc_length();
|
||||||
self.length = total_num - right.len();
|
self.length = total_num - right.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,7 +1154,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
|
pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
|
||||||
if let Some(root) = self.root.as_mut() {
|
if let Some(root) = self.root.as_mut() {
|
||||||
let (root, dormant_root) = DormantMutRef::new(root);
|
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 {
|
DrainFilterInner {
|
||||||
length: &mut self.length,
|
length: &mut self.length,
|
||||||
dormant_root: Some(dormant_root),
|
dormant_root: Some(dormant_root),
|
||||||
@ -1361,7 +1361,7 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
|
|||||||
fn into_iter(self) -> IntoIter<K, V> {
|
fn into_iter(self) -> IntoIter<K, V> {
|
||||||
let mut me = ManuallyDrop::new(self);
|
let mut me = ManuallyDrop::new(self);
|
||||||
if let Some(root) = me.root.take() {
|
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 }
|
IntoIter { front: Some(f), back: Some(b), length: me.length }
|
||||||
} else {
|
} else {
|
||||||
@ -2007,7 +2007,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn iter(&self) -> Iter<'_, K, V> {
|
pub fn iter(&self) -> Iter<'_, K, V> {
|
||||||
if let Some(root) = &self.root {
|
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 }
|
Iter { range: Range { front: Some(f), back: Some(b) }, length: self.length }
|
||||||
} else {
|
} else {
|
||||||
@ -2039,7 +2039,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
||||||
if let Some(root) = &mut self.root {
|
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 {
|
IterMut {
|
||||||
range: RangeMut { front: Some(f), back: Some(b), _marker: PhantomData },
|
range: RangeMut { front: Some(f), back: Some(b), _marker: PhantomData },
|
||||||
|
@ -286,7 +286,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
|||||||
// Safety: We have consumed self.handle and the reference returned.
|
// Safety: We have consumed self.handle and the reference returned.
|
||||||
let map = unsafe { self.dormant_map.awaken() };
|
let map = unsafe { self.dormant_map.awaken() };
|
||||||
let root = map.root.as_mut().unwrap();
|
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;
|
map.length += 1;
|
||||||
val_ptr
|
val_ptr
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
// Panics if the map (or the code navigating it) is corrupted.
|
// Panics if the map (or the code navigating it) is corrupted.
|
||||||
fn check_invariants(&self) {
|
fn check_invariants(&self) {
|
||||||
if let Some(root) = &self.root {
|
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
|
// Check the back pointers top-down, before we attempt to rely on
|
||||||
// more serious navigation code.
|
// more serious navigation code.
|
||||||
@ -92,7 +92,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
K: Debug,
|
K: Debug,
|
||||||
{
|
{
|
||||||
if let Some(root) = self.root.as_ref() {
|
if let Some(root) = self.root.as_ref() {
|
||||||
root.node_as_ref().dump_keys()
|
root.reborrow().dump_keys()
|
||||||
} else {
|
} else {
|
||||||
String::from("not yet allocated")
|
String::from("not yet allocated")
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::{self, MaybeUninit};
|
use core::mem::{self, MaybeUninit};
|
||||||
use core::ptr::{self, NonNull, Unique};
|
use core::ptr::{self, NonNull};
|
||||||
|
|
||||||
use crate::alloc::{AllocRef, Global, Layout};
|
use crate::alloc::{AllocRef, Global, Layout};
|
||||||
use crate::boxed::Box;
|
use crate::boxed::Box;
|
||||||
@ -114,100 +114,80 @@ impl<K, V> InternalNode<K, V> {
|
|||||||
/// of nodes it actually contains, and, partially due to this lack of information,
|
/// of nodes it actually contains, and, partially due to this lack of information,
|
||||||
/// has no destructor.
|
/// has no destructor.
|
||||||
struct BoxedNode<K, V> {
|
struct BoxedNode<K, V> {
|
||||||
ptr: Unique<LeafNode<K, V>>,
|
ptr: NonNull<LeafNode<K, V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> BoxedNode<K, V> {
|
impl<K, V> BoxedNode<K, V> {
|
||||||
fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
|
fn from_owned(ptr: NonNull<LeafNode<K, V>>) -> Self {
|
||||||
BoxedNode { ptr: Unique::from(Box::leak(node)) }
|
BoxedNode { ptr }
|
||||||
}
|
|
||||||
|
|
||||||
fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
|
|
||||||
BoxedNode { ptr: Unique::from(Box::leak(node)).cast() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_ptr(&self) -> NonNull<LeafNode<K, V>> {
|
fn as_ptr(&self) -> NonNull<LeafNode<K, V>> {
|
||||||
NonNull::from(self.ptr)
|
self.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An owned tree.
|
/// An owned tree.
|
||||||
///
|
///
|
||||||
/// Note that this does not have a destructor, and must be cleaned up manually.
|
/// Note that this does not have a destructor, and must be cleaned up manually.
|
||||||
pub struct Root<K, V> {
|
pub type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
|
||||||
node: BoxedNode<K, V>,
|
|
||||||
/// The number of levels below the root node.
|
|
||||||
height: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<K: Sync, V: Sync> Sync for Root<K, V> {}
|
|
||||||
unsafe impl<K: Send, V: Send> Send for Root<K, V> {}
|
|
||||||
|
|
||||||
impl<K, V> Root<K, V> {
|
impl<K, V> Root<K, V> {
|
||||||
/// Returns the number of levels below the root.
|
|
||||||
pub fn height(&self) -> usize {
|
|
||||||
self.height
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new owned tree, with its own root node that is initially empty.
|
/// Returns a new owned tree, with its own root node that is initially empty.
|
||||||
pub fn new_leaf() -> Self {
|
pub fn new_leaf() -> Self {
|
||||||
Root { node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), height: 0 }
|
NodeRef::new().forget_type()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows and returns an immutable reference to the node owned by the root.
|
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
|
||||||
pub fn node_as_ref(&self) -> NodeRef<marker::Immut<'_>, K, V, marker::LeafOrInternal> {
|
fn new() -> Self {
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
Self::from_new_leaf(Box::new(unsafe { LeafNode::new() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows and returns a mutable reference to the node owned by the root.
|
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
|
||||||
pub fn node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal> {
|
NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData }
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows and returns a mutable reference to the leaf node owned by the root.
|
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
|
||||||
/// # Safety
|
fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
|
||||||
/// The root node is a leaf.
|
NodeRef { height, node: NonNull::from(Box::leak(internal)).cast(), _marker: PhantomData }
|
||||||
unsafe fn leaf_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Leaf> {
|
}
|
||||||
debug_assert!(self.height == 0);
|
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows and returns a mutable reference to the internal node owned by the root.
|
impl<K, V, Type> NodeRef<marker::Owned, K, V, Type> {
|
||||||
/// # Safety
|
/// Mutably borrows the owned node. Unlike `reborrow_mut`, this is safe,
|
||||||
/// The root node is not a leaf.
|
/// because the return value cannot be used to destroy the node itself,
|
||||||
unsafe fn internal_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
|
/// and there cannot be other references to the tree (except during the
|
||||||
debug_assert!(self.height > 0);
|
/// process of `into_iter` or `drop`, but that is a horrific already).
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
pub fn borrow_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, Type> {
|
||||||
|
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_as_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, marker::LeafOrInternal> {
|
/// Slightly mutably borrows the owned node.
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
pub fn borrow_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, Type> {
|
||||||
}
|
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||||
|
|
||||||
pub fn into_ref(self) -> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
|
|
||||||
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Packs the reference, aware of type and height, into a type-agnostic pointer.
|
/// Packs the reference, aware of type and height, into a type-agnostic pointer.
|
||||||
fn into_boxed_node(self) -> BoxedNode<K, V> {
|
fn into_boxed_node(self) -> BoxedNode<K, V> {
|
||||||
self.node
|
BoxedNode::from_owned(self.node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
|
||||||
/// Adds a new internal node with a single edge pointing to the previous root node,
|
/// Adds a new internal node with a single edge pointing to the previous root node,
|
||||||
/// make that new node the root node, and return it. This increases the height by 1
|
/// make that new node the root node, and return it. This increases the height by 1
|
||||||
/// and is the opposite of `pop_internal_level`.
|
/// and is the opposite of `pop_internal_level`.
|
||||||
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
|
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
|
||||||
let mut new_node = Box::new(unsafe { InternalNode::new() });
|
let mut new_node = Box::new(unsafe { InternalNode::new() });
|
||||||
new_node.edges[0].write(unsafe { ptr::read(&mut self.node) });
|
new_node.edges[0].write(BoxedNode::from_owned(self.node));
|
||||||
|
let mut new_root = NodeRef::from_new_internal(new_node, self.height + 1);
|
||||||
|
new_root.borrow_mut().first_edge().correct_parent_link();
|
||||||
|
*self = new_root.forget_type();
|
||||||
|
|
||||||
self.node = BoxedNode::from_internal(new_node);
|
// `self.borrow_mut()`, except that we just forgot we're internal now:
|
||||||
self.height += 1;
|
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut ret = self.internal_node_as_mut();
|
|
||||||
ret.reborrow_mut().first_edge().correct_parent_link();
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the internal root node, using its first child as the new root node.
|
/// Removes the internal root node, using its first child as the new root node.
|
||||||
@ -216,19 +196,17 @@ impl<K, V> Root<K, V> {
|
|||||||
/// This decreases the height by 1 and is the opposite of `push_internal_level`.
|
/// This decreases the height by 1 and is the opposite of `push_internal_level`.
|
||||||
///
|
///
|
||||||
/// Requires exclusive access to the `Root` object but not to the root node;
|
/// Requires exclusive access to the `Root` object but not to the root node;
|
||||||
/// it will not invalidate existing handles or references to the root node.
|
/// it will not invalidate other handles or references to the root node.
|
||||||
///
|
///
|
||||||
/// Panics if there is no internal level, i.e., if the root node is a leaf.
|
/// Panics if there is no internal level, i.e., if the root node is a leaf.
|
||||||
pub fn pop_internal_level(&mut self) {
|
pub fn pop_internal_level(&mut self) {
|
||||||
assert!(self.height > 0);
|
assert!(self.height > 0);
|
||||||
|
|
||||||
let top = BoxedNode::as_ptr(&self.node);
|
let top = self.node;
|
||||||
|
|
||||||
let mut internal_node = unsafe { self.internal_node_as_mut() };
|
let internal_node = NodeRef { height: self.height, node: top, _marker: PhantomData };
|
||||||
let internal_node = NodeRef::as_internal_mut(&mut internal_node);
|
*self = internal_node.first_edge().descend();
|
||||||
self.node = unsafe { internal_node.edges[0].assume_init_read() };
|
self.borrow_mut().clear_parent_link();
|
||||||
self.height -= 1;
|
|
||||||
self.node_as_mut().clear_parent_link();
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Global.dealloc(top.cast(), Layout::new::<InternalNode<K, V>>());
|
Global.dealloc(top.cast(), Layout::new::<InternalNode<K, V>>());
|
||||||
@ -755,10 +733,10 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
|
|||||||
ForceResult::Leaf(_) => None,
|
ForceResult::Leaf(_) => None,
|
||||||
ForceResult::Internal(internal) => {
|
ForceResult::Internal(internal) => {
|
||||||
let boxed_node = ptr::read(internal.reborrow().edge_at(idx + 1));
|
let boxed_node = ptr::read(internal.reborrow().edge_at(idx + 1));
|
||||||
let mut edge = Root { node: boxed_node, height: internal.height - 1 };
|
let mut edge = Root::from_boxed_node(boxed_node, internal.height - 1);
|
||||||
// In practice, clearing the parent is a waste of time, because we will
|
// In practice, clearing the parent is a waste of time, because we will
|
||||||
// insert the node elsewhere and set its parent link again.
|
// insert the node elsewhere and set its parent link again.
|
||||||
edge.node_as_mut().clear_parent_link();
|
edge.borrow_mut().clear_parent_link();
|
||||||
Some(edge)
|
Some(edge)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -784,10 +762,10 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
|
|||||||
ForceResult::Internal(mut internal) => {
|
ForceResult::Internal(mut internal) => {
|
||||||
let boxed_node =
|
let boxed_node =
|
||||||
slice_remove(internal.reborrow_mut().into_edge_area_slice(), 0);
|
slice_remove(internal.reborrow_mut().into_edge_area_slice(), 0);
|
||||||
let mut edge = Root { node: boxed_node, height: internal.height - 1 };
|
let mut edge = Root::from_boxed_node(boxed_node, internal.height - 1);
|
||||||
// In practice, clearing the parent is a waste of time, because we will
|
// In practice, clearing the parent is a waste of time, because we will
|
||||||
// insert the node elsewhere and set its parent link again.
|
// insert the node elsewhere and set its parent link again.
|
||||||
edge.node_as_mut().clear_parent_link();
|
edge.borrow_mut().clear_parent_link();
|
||||||
|
|
||||||
internal.correct_childrens_parent_links(0..old_len);
|
internal.correct_childrens_parent_links(0..old_len);
|
||||||
|
|
||||||
@ -1028,17 +1006,17 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
|
|||||||
} else {
|
} else {
|
||||||
let (middle_kv_idx, insertion) = splitpoint(self.idx);
|
let (middle_kv_idx, insertion) = splitpoint(self.idx);
|
||||||
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
|
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
|
||||||
let (mut left, k, v, mut right) = middle.split();
|
let mut result = middle.split();
|
||||||
let mut insertion_edge = match insertion {
|
let mut insertion_edge = match insertion {
|
||||||
LeftOrRight::Left(insert_idx) => unsafe {
|
LeftOrRight::Left(insert_idx) => unsafe {
|
||||||
Handle::new_edge(left.reborrow_mut(), insert_idx)
|
Handle::new_edge(result.left.reborrow_mut(), insert_idx)
|
||||||
},
|
},
|
||||||
LeftOrRight::Right(insert_idx) => unsafe {
|
LeftOrRight::Right(insert_idx) => unsafe {
|
||||||
Handle::new_edge(right.leaf_node_as_mut(), insert_idx)
|
Handle::new_edge(result.right.borrow_mut(), insert_idx)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let val_ptr = insertion_edge.insert_fit(key, val);
|
let val_ptr = insertion_edge.insert_fit(key, val);
|
||||||
(InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), val_ptr)
|
(InsertResult::Split(result), val_ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1092,17 +1070,17 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
|
|||||||
} else {
|
} else {
|
||||||
let (middle_kv_idx, insertion) = splitpoint(self.idx);
|
let (middle_kv_idx, insertion) = splitpoint(self.idx);
|
||||||
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
|
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
|
||||||
let (mut left, k, v, mut right) = middle.split();
|
let mut result = middle.split();
|
||||||
let mut insertion_edge = match insertion {
|
let mut insertion_edge = match insertion {
|
||||||
LeftOrRight::Left(insert_idx) => unsafe {
|
LeftOrRight::Left(insert_idx) => unsafe {
|
||||||
Handle::new_edge(left.reborrow_mut(), insert_idx)
|
Handle::new_edge(result.left.reborrow_mut(), insert_idx)
|
||||||
},
|
},
|
||||||
LeftOrRight::Right(insert_idx) => unsafe {
|
LeftOrRight::Right(insert_idx) => unsafe {
|
||||||
Handle::new_edge(right.internal_node_as_mut(), insert_idx)
|
Handle::new_edge(result.right.borrow_mut(), insert_idx)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
insertion_edge.insert_fit(key, val, edge);
|
insertion_edge.insert_fit(key, val, edge);
|
||||||
InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right })
|
InsertResult::Split(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,16 +1102,16 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
|
|||||||
(InsertResult::Fit(handle), ptr) => {
|
(InsertResult::Fit(handle), ptr) => {
|
||||||
return (InsertResult::Fit(handle.forget_node_type()), ptr);
|
return (InsertResult::Fit(handle.forget_node_type()), ptr);
|
||||||
}
|
}
|
||||||
(InsertResult::Split(split), val_ptr) => (split, val_ptr),
|
(InsertResult::Split(split), val_ptr) => (split.forget_node_type(), val_ptr),
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
split = match split.left.ascend() {
|
split = match split.left.ascend() {
|
||||||
Ok(parent) => match parent.insert(split.k, split.v, split.right) {
|
Ok(parent) => match parent.insert(split.kv.0, split.kv.1, split.right) {
|
||||||
InsertResult::Fit(handle) => {
|
InsertResult::Fit(handle) => {
|
||||||
return (InsertResult::Fit(handle.forget_node_type()), val_ptr);
|
return (InsertResult::Fit(handle.forget_node_type()), val_ptr);
|
||||||
}
|
}
|
||||||
InsertResult::Split(split) => split,
|
InsertResult::Split(split) => split.forget_node_type(),
|
||||||
},
|
},
|
||||||
Err(root) => {
|
Err(root) => {
|
||||||
return (InsertResult::Split(SplitResult { left: root, ..split }), val_ptr);
|
return (InsertResult::Split(SplitResult { left: root, ..split }), val_ptr);
|
||||||
@ -1239,14 +1217,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
|
|||||||
/// - The key and value pointed to by this handle are extracted.
|
/// - The key and value pointed to by this handle are extracted.
|
||||||
/// - All the key/value pairs to the right of this handle are put into a newly
|
/// - All the key/value pairs to the right of this handle are put into a newly
|
||||||
/// allocated node.
|
/// allocated node.
|
||||||
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
|
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut new_node = Box::new(LeafNode::new());
|
let mut new_node = Box::new(LeafNode::new());
|
||||||
|
|
||||||
let (k, v) = self.split_leaf_data(&mut new_node);
|
let kv = self.split_leaf_data(&mut new_node);
|
||||||
|
|
||||||
let right = Root { node: BoxedNode::from_leaf(new_node), height: 0 };
|
let right = NodeRef::from_new_leaf(new_node);
|
||||||
(self.node, k, v, right)
|
SplitResult { left: self.node, kv, right }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,7 +1250,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
|
|||||||
/// - The key and value pointed to by this handle are extracted.
|
/// - The key and value pointed to by this handle are extracted.
|
||||||
/// - All the edges and key/value pairs to the right of this handle are put into
|
/// - All the edges and key/value pairs to the right of this handle are put into
|
||||||
/// a newly allocated node.
|
/// a newly allocated node.
|
||||||
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Internal>, K, V, Root<K, V>) {
|
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Internal> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut new_node = Box::new(InternalNode::new());
|
let mut new_node = Box::new(InternalNode::new());
|
||||||
let new_len = self.split_new_node_len();
|
let new_len = self.split_new_node_len();
|
||||||
@ -1282,14 +1260,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
|
|||||||
new_node.edges.as_mut_ptr(),
|
new_node.edges.as_mut_ptr(),
|
||||||
new_len + 1,
|
new_len + 1,
|
||||||
);
|
);
|
||||||
let (k, v) = self.split_leaf_data(&mut new_node.data);
|
let kv = self.split_leaf_data(&mut new_node.data);
|
||||||
|
|
||||||
let height = self.node.height;
|
let height = self.node.height;
|
||||||
let mut right = Root { node: BoxedNode::from_internal(new_node), height };
|
let mut right = NodeRef::from_new_internal(new_node, height);
|
||||||
|
|
||||||
right.internal_node_as_mut().correct_childrens_parent_links(0..=new_len);
|
right.borrow_mut().correct_childrens_parent_links(0..=new_len);
|
||||||
|
|
||||||
(self.node, k, v, right)
|
SplitResult { left: self.node, kv, right }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1756,20 +1734,30 @@ pub enum ForceResult<Leaf, Internal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Result of insertion, when a node needed to expand beyond its capacity.
|
/// Result of insertion, when a node needed to expand beyond its capacity.
|
||||||
/// Does not distinguish between `Leaf` and `Internal` because `Root` doesn't.
|
pub struct SplitResult<'a, K, V, NodeType> {
|
||||||
pub struct SplitResult<'a, K, V> {
|
// Altered node in existing tree with elements and edges that belong to the left of `kv`.
|
||||||
// Altered node in existing tree with elements and edges that belong to the left of `k`.
|
pub left: NodeRef<marker::Mut<'a>, K, V, NodeType>,
|
||||||
pub left: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>,
|
|
||||||
// Some key and value split off, to be inserted elsewhere.
|
// Some key and value split off, to be inserted elsewhere.
|
||||||
pub k: K,
|
pub kv: (K, V),
|
||||||
pub v: V,
|
// Owned, unattached, new node with elements and edges that belong to the right of `kv`.
|
||||||
// Owned, unattached, new node with elements and edges that belong to the right of `k`.
|
pub right: NodeRef<marker::Owned, K, V, NodeType>,
|
||||||
pub right: Root<K, V>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum InsertResult<'a, K, V, Type> {
|
impl<'a, K, V> SplitResult<'a, K, V, marker::Leaf> {
|
||||||
Fit(Handle<NodeRef<marker::Mut<'a>, K, V, Type>, marker::KV>),
|
pub fn forget_node_type(self) -> SplitResult<'a, K, V, marker::LeafOrInternal> {
|
||||||
Split(SplitResult<'a, K, V>),
|
SplitResult { left: self.left.forget_type(), kv: self.kv, right: self.right.forget_type() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, K, V> SplitResult<'a, K, V, marker::Internal> {
|
||||||
|
pub fn forget_node_type(self) -> SplitResult<'a, K, V, marker::LeafOrInternal> {
|
||||||
|
SplitResult { left: self.left.forget_type(), kv: self.kv, right: self.right.forget_type() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum InsertResult<'a, K, V, NodeType> {
|
||||||
|
Fit(Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV>),
|
||||||
|
Split(SplitResult<'a, K, V, NodeType>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod marker {
|
pub mod marker {
|
||||||
|
@ -74,16 +74,19 @@ fn test_splitpoint() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_partial_cmp_eq() {
|
fn test_partial_cmp_eq() {
|
||||||
let mut root1: Root<i32, ()> = Root::new_leaf();
|
let mut root1 = NodeRef::new();
|
||||||
let mut leaf1 = unsafe { root1.leaf_node_as_mut() };
|
let mut leaf1 = root1.borrow_mut();
|
||||||
leaf1.push(1, ());
|
leaf1.push(1, ());
|
||||||
|
let mut root1 = root1.forget_type();
|
||||||
root1.push_internal_level();
|
root1.push_internal_level();
|
||||||
let root2: Root<i32, ()> = Root::new_leaf();
|
let root2 = Root::new_leaf();
|
||||||
|
root1.reborrow().assert_back_pointers();
|
||||||
|
root2.reborrow().assert_back_pointers();
|
||||||
|
|
||||||
let leaf_edge_1a = root1.node_as_ref().first_leaf_edge().forget_node_type();
|
let leaf_edge_1a = root1.reborrow().first_leaf_edge().forget_node_type();
|
||||||
let leaf_edge_1b = root1.node_as_ref().last_leaf_edge().forget_node_type();
|
let leaf_edge_1b = root1.reborrow().last_leaf_edge().forget_node_type();
|
||||||
let top_edge_1 = root1.node_as_ref().first_edge();
|
let top_edge_1 = root1.reborrow().first_edge();
|
||||||
let top_edge_2 = root2.node_as_ref().first_edge();
|
let top_edge_2 = root2.reborrow().first_edge();
|
||||||
|
|
||||||
assert!(leaf_edge_1a == leaf_edge_1a);
|
assert!(leaf_edge_1a == leaf_edge_1a);
|
||||||
assert!(leaf_edge_1a != leaf_edge_1b);
|
assert!(leaf_edge_1a != leaf_edge_1b);
|
||||||
@ -100,8 +103,8 @@ fn test_partial_cmp_eq() {
|
|||||||
assert_eq!(top_edge_1.partial_cmp(&top_edge_2), None);
|
assert_eq!(top_edge_1.partial_cmp(&top_edge_2), None);
|
||||||
|
|
||||||
root1.pop_internal_level();
|
root1.pop_internal_level();
|
||||||
unsafe { root1.into_ref().deallocate_and_ascend() };
|
unsafe { root1.deallocate_and_ascend() };
|
||||||
unsafe { root2.into_ref().deallocate_and_ascend() };
|
unsafe { root2.deallocate_and_ascend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -9,7 +9,7 @@ impl<K, V> Root<K, V> {
|
|||||||
K: Borrow<Q>,
|
K: Borrow<Q>,
|
||||||
{
|
{
|
||||||
debug_assert!(right_root.height() == 0);
|
debug_assert!(right_root.height() == 0);
|
||||||
debug_assert!(right_root.node_as_ref().len() == 0);
|
debug_assert!(right_root.len() == 0);
|
||||||
|
|
||||||
let left_root = self;
|
let left_root = self;
|
||||||
for _ in 0..left_root.height() {
|
for _ in 0..left_root.height() {
|
||||||
@ -17,8 +17,8 @@ impl<K, V> Root<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut left_node = left_root.node_as_mut();
|
let mut left_node = left_root.borrow_mut();
|
||||||
let mut right_node = right_root.node_as_mut();
|
let mut right_node = right_root.borrow_mut();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut split_edge = match search_node(left_node, key) {
|
let mut split_edge = match search_node(left_node, key) {
|
||||||
@ -48,7 +48,7 @@ impl<K, V> Root<K, V> {
|
|||||||
|
|
||||||
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
|
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
|
||||||
fn fix_top(&mut self) {
|
fn fix_top(&mut self) {
|
||||||
while self.height() > 0 && self.node_as_ref().len() == 0 {
|
while self.height() > 0 && self.len() == 0 {
|
||||||
self.pop_internal_level();
|
self.pop_internal_level();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ impl<K, V> Root<K, V> {
|
|||||||
self.fix_top();
|
self.fix_top();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut cur_node = self.node_as_mut();
|
let mut cur_node = self.borrow_mut();
|
||||||
|
|
||||||
while let Internal(node) = cur_node.force() {
|
while let Internal(node) = cur_node.force() {
|
||||||
let mut last_kv = node.last_kv().consider_for_balancing();
|
let mut last_kv = node.last_kv().consider_for_balancing();
|
||||||
@ -83,7 +83,7 @@ impl<K, V> Root<K, V> {
|
|||||||
self.fix_top();
|
self.fix_top();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut cur_node = self.node_as_mut();
|
let mut cur_node = self.borrow_mut();
|
||||||
|
|
||||||
while let Internal(node) = cur_node.force() {
|
while let Internal(node) = cur_node.force() {
|
||||||
let mut first_kv = node.first_kv().consider_for_balancing();
|
let mut first_kv = node.first_kv().consider_for_balancing();
|
||||||
|
@ -207,25 +207,26 @@ class StdRefCellProvider:
|
|||||||
yield "borrow", self.borrow
|
yield "borrow", self.borrow
|
||||||
|
|
||||||
|
|
||||||
# Yields children (in a provider's sense of the word) for a tree headed by a BoxedNode.
|
# Yields children (in a provider's sense of the word) for a BTreeMap.
|
||||||
# In particular, yields each key/value pair in the node and in any child nodes.
|
def children_of_btree_map(map):
|
||||||
def children_of_node(boxed_node, height):
|
# Yields each key/value pair in the node and in any child nodes.
|
||||||
|
def children_of_node(node_ptr, height):
|
||||||
def cast_to_internal(node):
|
def cast_to_internal(node):
|
||||||
internal_type_name = node.type.target().name.replace("LeafNode", "InternalNode", 1)
|
internal_type_name = node.type.target().name.replace("LeafNode", "InternalNode", 1)
|
||||||
internal_type = lookup_type(internal_type_name)
|
internal_type = lookup_type(internal_type_name)
|
||||||
return node.cast(internal_type.pointer())
|
return node.cast(internal_type.pointer())
|
||||||
|
|
||||||
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
|
|
||||||
leaf = node_ptr.dereference()
|
leaf = node_ptr.dereference()
|
||||||
keys = leaf["keys"]
|
keys = leaf["keys"]
|
||||||
vals = leaf["vals"]
|
vals = leaf["vals"]
|
||||||
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
|
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
|
||||||
length = int(leaf["len"])
|
length = leaf["len"]
|
||||||
|
|
||||||
for i in xrange(0, length + 1):
|
for i in xrange(0, length + 1):
|
||||||
if height > 0:
|
if height > 0:
|
||||||
boxed_child_node = edges[i]["value"]["value"]
|
boxed_child_node = edges[i]["value"]["value"]
|
||||||
for child in children_of_node(boxed_child_node, height - 1):
|
child_node = unwrap_unique_or_non_null(boxed_child_node["ptr"])
|
||||||
|
for child in children_of_node(child_node, height - 1):
|
||||||
yield child
|
yield child
|
||||||
if i < length:
|
if i < length:
|
||||||
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
|
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
|
||||||
@ -233,16 +234,16 @@ def children_of_node(boxed_node, height):
|
|||||||
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else "()"
|
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else "()"
|
||||||
yield key, val
|
yield key, val
|
||||||
|
|
||||||
|
|
||||||
# Yields children for a BTreeMap.
|
|
||||||
def children_of_map(map):
|
|
||||||
if map["length"] > 0:
|
if map["length"] > 0:
|
||||||
root = map["root"]
|
root = map["root"]
|
||||||
if root.type.name.startswith("core::option::Option<"):
|
if root.type.name.startswith("core::option::Option<"):
|
||||||
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
|
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
|
||||||
boxed_root_node = root["node"]
|
node_ptr = root["node"]
|
||||||
|
if node_ptr.type.name.startswith("alloc::collections::btree::node::BoxedNode<"):
|
||||||
|
node_ptr = node_ptr["ptr"]
|
||||||
|
node_ptr = unwrap_unique_or_non_null(node_ptr)
|
||||||
height = root["height"]
|
height = root["height"]
|
||||||
for child in children_of_node(boxed_root_node, height):
|
for child in children_of_node(node_ptr, height):
|
||||||
yield child
|
yield child
|
||||||
|
|
||||||
|
|
||||||
@ -255,7 +256,7 @@ class StdBTreeSetProvider:
|
|||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
inner_map = self.valobj["map"]
|
inner_map = self.valobj["map"]
|
||||||
for i, (child, _) in enumerate(children_of_map(inner_map)):
|
for i, (child, _) in enumerate(children_of_btree_map(inner_map)):
|
||||||
yield "[{}]".format(i), child
|
yield "[{}]".format(i), child
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -271,7 +272,7 @@ class StdBTreeMapProvider:
|
|||||||
return "BTreeMap(size={})".format(self.valobj["length"])
|
return "BTreeMap(size={})".format(self.valobj["length"])
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
for i, (key, val) in enumerate(children_of_map(self.valobj)):
|
for i, (key, val) in enumerate(children_of_btree_map(self.valobj)):
|
||||||
yield "key{}".format(i), key
|
yield "key{}".format(i), key
|
||||||
yield "val{}".format(i), val
|
yield "val{}".format(i), val
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ fn main() {
|
|||||||
btree_set.insert(i);
|
btree_set.insert(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut empty_btree_set: BTreeSet<i32> = BTreeSet::new();
|
let empty_btree_set: BTreeSet<i32> = BTreeSet::new();
|
||||||
|
|
||||||
// BTreeMap
|
// BTreeMap
|
||||||
let mut btree_map = BTreeMap::new();
|
let mut btree_map = BTreeMap::new();
|
||||||
@ -110,7 +110,7 @@ fn main() {
|
|||||||
btree_map.insert(i, i);
|
btree_map.insert(i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut empty_btree_map: BTreeMap<i32, u32> = BTreeMap::new();
|
let empty_btree_map: BTreeMap<i32, u32> = BTreeMap::new();
|
||||||
|
|
||||||
let mut option_btree_map: BTreeMap<bool, Option<bool>> = BTreeMap::new();
|
let mut option_btree_map: BTreeMap<bool, Option<bool>> = BTreeMap::new();
|
||||||
option_btree_map.insert(false, None);
|
option_btree_map.insert(false, None);
|
||||||
|
Loading…
Reference in New Issue
Block a user