diff options
| author | pravic <[email protected]> | 2016-04-12 17:44:24 +0300 |
|---|---|---|
| committer | pravic <[email protected]> | 2016-04-12 17:44:24 +0300 |
| commit | bcb1fb5ba7ecf8b208bd6053e689ad8e87b0654d (patch) | |
| tree | 8de2327e8f25394e7c30324fddb4b7bcbf9a9f56 /libcollections/btree/node.rs | |
| parent | liballoc (diff) | |
| download | kmd-env-rs-bcb1fb5ba7ecf8b208bd6053e689ad8e87b0654d.tar.xz kmd-env-rs-bcb1fb5ba7ecf8b208bd6053e689ad8e87b0654d.zip | |
libcollections
Diffstat (limited to 'libcollections/btree/node.rs')
| -rw-r--r-- | libcollections/btree/node.rs | 1132 |
1 files changed, 1132 insertions, 0 deletions
diff --git a/libcollections/btree/node.rs b/libcollections/btree/node.rs new file mode 100644 index 0000000..8ae23a6 --- /dev/null +++ b/libcollections/btree/node.rs @@ -0,0 +1,1132 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This is an attempt at an implementation following the ideal +// +// ``` +// struct BTreeMap<K, V> { +// height: usize, +// root: Option<Box<Node<K, V, height>>> +// } +// +// struct Node<K, V, height: usize> { +// keys: [K; 2 * B - 1], +// vals: [V; 2 * B - 1], +// edges: if height > 0 { +// [Box<Node<K, V, height - 1>>; 2 * B] +// } else { () }, +// parent: *const Node<K, V, height + 1>, +// parent_idx: u16, +// len: u16, +// } +// ``` +// +// Since Rust doesn't actually have dependent types and polymorphic recursion, +// we make do with lots of unsafety. + +use alloc::heap; +use core::marker::PhantomData; +use core::mem; +use core::nonzero::NonZero; +use core::ptr::{self, Unique}; +use core::slice; + +use boxed::Box; + +const B: usize = 6; +pub const CAPACITY: usize = 2 * B - 1; + +struct LeafNode<K, V> { + keys: [K; CAPACITY], + vals: [V; CAPACITY], + parent: *const InternalNode<K, V>, + parent_idx: u16, + len: u16, +} + +impl<K, V> LeafNode<K, V> { + unsafe fn new() -> Self { + LeafNode { + keys: mem::uninitialized(), + vals: mem::uninitialized(), + parent: ptr::null(), + parent_idx: mem::uninitialized(), + len: 0 + } + } +} + +// We use repr(C) so that a pointer to an internal node can be +// directly used as a pointer to a leaf node +#[repr(C)] +struct InternalNode<K, V> { + data: LeafNode<K, V>, + edges: [BoxedNode<K, V>; 2 * B], +} + +impl<K, V> InternalNode<K, V> { + unsafe fn new() -> Self { + InternalNode { + data: LeafNode::new(), + edges: mem::uninitialized() + } + } +} + +struct BoxedNode<K, V> { + ptr: Unique<LeafNode<K, V>> // we don't know if this points to a leaf node or an internal node +} + +impl<K, V> BoxedNode<K, V> { + fn from_leaf(node: Box<LeafNode<K, V>>) -> Self { + unsafe { + BoxedNode { ptr: Unique::new(Box::into_raw(node)) } + } + } + + fn from_internal(node: Box<InternalNode<K, V>>) -> Self { + unsafe { + BoxedNode { ptr: Unique::new(Box::into_raw(node) as *mut LeafNode<K, V>) } + } + } + + unsafe fn from_ptr(ptr: NonZero<*const LeafNode<K, V>>) -> Self { + BoxedNode { ptr: Unique::new(*ptr as *mut LeafNode<K, V>) } + } + + fn as_ptr(&self) -> NonZero<*const LeafNode<K, V>> { + unsafe { + NonZero::new(*self.ptr as *const LeafNode<K, V>) + } + } +} + +/// An owned tree. Note that despite being owned, this does not have a destructor, +/// and must be cleaned up manually. +pub struct Root<K, V> { + node: BoxedNode<K, V>, + 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> { + pub fn new_leaf() -> Self { + Root { + node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), + height: 0 + } + } + + pub fn as_ref(&self) + -> NodeRef<marker::Immut, K, V, marker::LeafOrInternal> { + NodeRef { + height: self.height, + node: self.node.as_ptr(), + root: self as *const _ as *mut _, + _marker: PhantomData, + } + } + + pub fn as_mut(&mut self) + -> NodeRef<marker::Mut, K, V, marker::LeafOrInternal> { + NodeRef { + height: self.height, + node: self.node.as_ptr(), + root: self as *mut _, + _marker: PhantomData, + } + } + + pub fn into_ref(self) + -> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> { + NodeRef { + height: self.height, + node: self.node.as_ptr(), + root: ptr::null_mut(), // FIXME: Is there anything better to do here? + _marker: PhantomData, + } + } + + /// Add a new internal node with a single edge, pointing to the previous root, and make that + /// new node the root. This increases the height by 1 and is the opposite of `pop_level`. + pub fn push_level(&mut self) + -> NodeRef<marker::Mut, K, V, marker::Internal> { + let mut new_node = Box::new(unsafe { InternalNode::new() }); + new_node.edges[0] = unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }; + + self.node = BoxedNode::from_internal(new_node); + self.height += 1; + + let mut ret = NodeRef { + height: self.height, + node: self.node.as_ptr(), + root: self as *mut _, + _marker: PhantomData + }; + + unsafe { + ret.reborrow_mut().first_edge().correct_parent_link(); + } + + ret + } + + /// Remove the root node, using its first child as the new root. This cannot be called when + /// the tree consists only of a leaf node. As it is intended only to be called when the root + /// has only one edge, no cleanup is done on any of the other children are elements of the root. + /// This decreases the height by 1 and is the opposite of `push_level`. + pub fn pop_level(&mut self) { + debug_assert!(self.height > 0); + + let top = *self.node.ptr as *mut u8; + + self.node = unsafe { + BoxedNode::from_ptr(self.as_mut() + .cast_unchecked::<marker::Internal>() + .first_edge() + .descend() + .node) + }; + self.height -= 1; + self.as_mut().as_leaf_mut().parent = ptr::null(); + + unsafe { + heap::deallocate( + top, + mem::size_of::<InternalNode<K, V>>(), + mem::align_of::<InternalNode<K, V>>() + ); + } + } +} + +// N.B. `NodeRef` is always covariant in `K` and `V`, even when the `BorrowType` +// is `Mut`. This is technically wrong, but cannot result in any unsafety due to +// internal use of `NodeRef` because we stay completely generic over `K` and `V`. +// However, whenever a public type wraps `NodeRef`, make sure that it has the +// correct variance. +/// A reference to a node. +/// +/// This type has a number of paramaters that controls how it acts: +/// - `BorrowType`: This can be `Immut<'a>` or `Mut<'a>` for some `'a` or `Owned`. +/// When this is `Immut<'a>`, the `NodeRef` acts roughly like `&'a Node`, +/// when this is `Mut<'a>`, the `NodeRef` acts roughly like `&'a mut Node`, +/// and when this is `Owned`, the `NodeRef` acts roughly like `Box<Node>`. +/// - `K` and `V`: These control what types of things are stored in the nodes. +/// - `Type`: This can be `Leaf`, `Internal`, or `LeafOrInternal`. When this is +/// `Leaf`, the `NodeRef` points to a leaf node, when this is `Internal` the +/// `NodeRef` points to an internal node, and when this is `LeafOrInternal` the +/// `NodeRef` could be pointing to either type of node. +pub struct NodeRef<BorrowType, K, V, Type> { + height: usize, + node: NonZero<*const LeafNode<K, V>>, + root: *const Root<K, V>, + _marker: PhantomData<(BorrowType, Type)> +} + +impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef<marker::Immut<'a>, K, V, Type> { } +impl<'a, K: 'a, V: 'a, Type> Clone for NodeRef<marker::Immut<'a>, K, V, Type> { + fn clone(&self) -> Self { + *self + } +} + +unsafe impl<BorrowType, K: Sync, V: Sync, Type> Sync + for NodeRef<BorrowType, K, V, Type> { } + +unsafe impl<'a, K: Sync + 'a, V: Sync + 'a, Type> Send + for NodeRef<marker::Immut<'a>, K, V, Type> { } +unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send + for NodeRef<marker::Mut<'a>, K, V, Type> { } +unsafe impl<K: Send, V: Send, Type> Send + for NodeRef<marker::Owned, K, V, Type> { } + +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> { + fn as_internal(&self) -> &InternalNode<K, V> { + unsafe { + &*(*self.node as *const InternalNode<K, V>) + } + } +} + +impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { + fn as_internal_mut(&mut self) -> &mut InternalNode<K, V> { + unsafe { + &mut *(*self.node as *mut InternalNode<K, V>) + } + } +} + + +impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { + pub fn len(&self) -> usize { + self.as_leaf().len as usize + } + + pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + } + } + + fn reborrow<'a>(&'a self) -> NodeRef<marker::Immut<'a>, K, V, Type> { + NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + } + } + + fn as_leaf(&self) -> &LeafNode<K, V> { + unsafe { + &**self.node + } + } + + pub fn keys(&self) -> &[K] { + self.reborrow().into_slices().0 + } + + pub fn vals(&self) -> &[V] { + self.reborrow().into_slices().1 + } + + pub fn ascend(self) -> Result< + Handle< + NodeRef< + BorrowType, + K, V, + marker::Internal + >, + marker::Edge + >, + Self + > { + if self.as_leaf().parent.is_null() { + Err(self) + } else { + Ok(Handle { + node: NodeRef { + height: self.height + 1, + node: unsafe { + NonZero::new(self.as_leaf().parent as *mut LeafNode<K, V>) + }, + root: self.root, + _marker: PhantomData + }, + idx: self.as_leaf().parent_idx as usize, + _marker: PhantomData + }) + } + } + + pub fn first_edge(self) -> Handle<Self, marker::Edge> { + Handle::new_edge(self, 0) + } + + pub fn last_edge(self) -> Handle<Self, marker::Edge> { + let len = self.len(); + Handle::new_edge(self, len) + } +} + +impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> { + pub unsafe fn deallocate_and_ascend(self) -> Option< + Handle< + NodeRef< + marker::Owned, + K, V, + marker::Internal + >, + marker::Edge + > + > { + let ptr = self.as_leaf() as *const LeafNode<K, V> as *const u8 as *mut u8; + let ret = self.ascend().ok(); + heap::deallocate(ptr, mem::size_of::<LeafNode<K, V>>(), mem::align_of::<LeafNode<K, V>>()); + ret + } +} + +impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> { + pub unsafe fn deallocate_and_ascend(self) -> Option< + Handle< + NodeRef< + marker::Owned, + K, V, + marker::Internal + >, + marker::Edge + > + > { + let ptr = self.as_internal() as *const InternalNode<K, V> as *const u8 as *mut u8; + let ret = self.ascend().ok(); + heap::deallocate( + ptr, + mem::size_of::<InternalNode<K, V>>(), + mem::align_of::<InternalNode<K, V>>() + ); + ret + } +} + +impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> { + unsafe fn cast_unchecked<NewType>(&mut self) + -> NodeRef<marker::Mut, K, V, NewType> { + + NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + } + } + + unsafe fn reborrow_mut(&mut self) -> NodeRef<marker::Mut, K, V, Type> { + NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + } + } + + fn as_leaf_mut(&mut self) -> &mut LeafNode<K, V> { + unsafe { + &mut *(*self.node as *mut LeafNode<K, V>) + } + } + + pub fn keys_mut(&mut self) -> &mut [K] { + unsafe { self.reborrow_mut().into_slices_mut().0 } + } + + pub fn vals_mut(&mut self) -> &mut [V] { + unsafe { self.reborrow_mut().into_slices_mut().1 } + } +} + +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { + pub fn into_slices(self) -> (&'a [K], &'a [V]) { + unsafe { + ( + slice::from_raw_parts( + self.as_leaf().keys.as_ptr(), + self.len() + ), + slice::from_raw_parts( + self.as_leaf().vals.as_ptr(), + self.len() + ) + ) + } + } +} + +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { + pub fn into_root_mut(self) -> &'a mut Root<K, V> { + unsafe { + &mut *(self.root as *mut Root<K, V>) + } + } + + pub fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) { + unsafe { + ( + slice::from_raw_parts_mut( + &mut self.as_leaf_mut().keys as *mut [K] as *mut K, + self.len() + ), + slice::from_raw_parts_mut( + &mut self.as_leaf_mut().vals as *mut [V] as *mut V, + self.len() + ) + ) + } + } +} + +impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> { + pub fn push(&mut self, key: K, val: V) { + // Necessary for correctness, but this is an internal module + debug_assert!(self.len() < CAPACITY); + + let idx = self.len(); + + unsafe { + ptr::write(self.keys_mut().get_unchecked_mut(idx), key); + ptr::write(self.vals_mut().get_unchecked_mut(idx), val); + } + + self.as_leaf_mut().len += 1; + } + + pub fn push_front(&mut self, key: K, val: V) { + // Necessary for correctness, but this is an internal module + debug_assert!(self.len() < CAPACITY); + + unsafe { + slice_insert(self.keys_mut(), 0, key); + slice_insert(self.vals_mut(), 0, val); + } + + self.as_leaf_mut().len += 1; + } +} + +impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { + pub fn push(&mut self, key: K, val: V, edge: Root<K, V>) { + // Necessary for correctness, but this is an internal module + debug_assert!(edge.height == self.height - 1); + debug_assert!(self.len() < CAPACITY); + + let idx = self.len(); + + unsafe { + ptr::write(self.keys_mut().get_unchecked_mut(idx), key); + ptr::write(self.vals_mut().get_unchecked_mut(idx), val); + ptr::write(self.as_internal_mut().edges.get_unchecked_mut(idx + 1), edge.node); + + self.as_leaf_mut().len += 1; + + Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link(); + } + } + + pub fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) { + // Necessary for correctness, but this is an internal module + debug_assert!(edge.height == self.height - 1); + debug_assert!(self.len() < CAPACITY); + + unsafe { + slice_insert(self.keys_mut(), 0, key); + slice_insert(self.vals_mut(), 0, val); + slice_insert( + slice::from_raw_parts_mut( + self.as_internal_mut().edges.as_mut_ptr(), + self.len()+1 + ), + 0, + edge.node + ); + + self.as_leaf_mut().len += 1; + + for i in 0..self.len()+1 { + Handle::new_edge(self.reborrow_mut(), i).correct_parent_link(); + } + } + + } +} + +impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { + pub fn pop(&mut self) -> (K, V, Option<Root<K, V>>) { + // Necessary for correctness, but this is an internal module + debug_assert!(self.len() > 0); + + let idx = self.len() - 1; + + unsafe { + let key = ptr::read(self.keys().get_unchecked(idx)); + let val = ptr::read(self.vals().get_unchecked(idx)); + let edge = match self.reborrow_mut().force() { + ForceResult::Leaf(_) => None, + ForceResult::Internal(internal) => { + let edge = ptr::read(internal.as_internal().edges.get_unchecked(idx + 1)); + let mut new_root = Root { node: edge, height: internal.height - 1 }; + new_root.as_mut().as_leaf_mut().parent = ptr::null(); + Some(new_root) + } + }; + + self.as_leaf_mut().len -= 1; + (key, val, edge) + } + } + + pub fn pop_front(&mut self) -> (K, V, Option<Root<K, V>>) { + // Necessary for correctness, but this is an internal module + debug_assert!(self.len() > 0); + + let old_len = self.len(); + + unsafe { + let key = slice_remove(self.keys_mut(), 0); + let val = slice_remove(self.vals_mut(), 0); + let edge = match self.reborrow_mut().force() { + ForceResult::Leaf(_) => None, + ForceResult::Internal(mut internal) => { + let edge = slice_remove( + slice::from_raw_parts_mut( + internal.as_internal_mut().edges.as_mut_ptr(), + old_len+1 + ), + 0 + ); + + let mut new_root = Root { node: edge, height: internal.height - 1 }; + new_root.as_mut().as_leaf_mut().parent = ptr::null(); + + for i in 0..old_len { + Handle::new_edge(internal.reborrow_mut(), i).correct_parent_link(); + } + + Some(new_root) + } + }; + + self.as_leaf_mut().len -= 1; + + (key, val, edge) + } + } +} + +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + pub fn force(self) -> ForceResult< + NodeRef<BorrowType, K, V, marker::Leaf>, + NodeRef<BorrowType, K, V, marker::Internal> + > { + if self.height == 0 { + ForceResult::Leaf(NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + }) + } else { + ForceResult::Internal(NodeRef { + height: self.height, + node: self.node, + root: self.root, + _marker: PhantomData + }) + } + } +} + +pub struct Handle<Node, Type> { + node: Node, + idx: usize, + _marker: PhantomData<Type> +} + +impl<Node: Copy, Type> Copy for Handle<Node, Type> { } +impl<Node: Copy, Type> Clone for Handle<Node, Type> { + fn clone(&self) -> Self { + *self + } +} + +impl<Node, Type> Handle<Node, Type> { + pub fn into_node(self) -> Node { + self.node + } +} + +impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::KV> { + pub fn new_kv(node: NodeRef<BorrowType, K, V, NodeType>, idx: usize) -> Self { + // Necessary for correctness, but in a private module + debug_assert!(idx < node.len()); + + Handle { + node: node, + idx: idx, + _marker: PhantomData + } + } + + pub fn left_edge(self) -> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::Edge> { + Handle::new_edge(self.node, self.idx) + } + + pub fn right_edge(self) -> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::Edge> { + Handle::new_edge(self.node, self.idx + 1) + } +} + +impl<BorrowType, K, V, NodeType, HandleType> PartialEq + for Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> { + + fn eq(&self, other: &Self) -> bool { + self.node.node == other.node.node && self.idx == other.idx + } +} + +impl<BorrowType, K, V, NodeType, HandleType> + Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType> { + + pub fn reborrow(&self) + -> Handle<NodeRef<marker::Immut, K, V, NodeType>, HandleType> { + + // We can't use Handle::new_kv or Handle::new_edge because we don't know our type + Handle { + node: self.node.reborrow(), + idx: self.idx, + _marker: PhantomData + } + } +} + +impl<'a, K, V, NodeType, HandleType> + Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, HandleType> { + + pub unsafe fn reborrow_mut(&mut self) + -> Handle<NodeRef<marker::Mut, K, V, NodeType>, HandleType> { + + // We can't use Handle::new_kv or Handle::new_edge because we don't know our type + Handle { + node: self.node.reborrow_mut(), + idx: self.idx, + _marker: PhantomData + } + } +} + +impl<BorrowType, K, V, NodeType> + Handle<NodeRef<BorrowType, K, V, NodeType>, marker::Edge> { + + pub fn new_edge(node: NodeRef<BorrowType, K, V, NodeType>, idx: usize) -> Self { + // Necessary for correctness, but in a private module + debug_assert!(idx <= node.len()); + + Handle { + node: node, + idx: idx, + _marker: PhantomData + } + } + + pub fn left_kv(self) + -> Result<Handle<NodeRef<BorrowType, K, V, NodeType>, marker::KV>, Self> { + + if self.idx > 0 { + Ok(Handle::new_kv(self.node, self.idx - 1)) + } else { + Err(self) + } + } + + pub fn right_kv(self) + -> Result<Handle<NodeRef<BorrowType, K, V, NodeType>, marker::KV>, Self> { + + if self.idx < self.node.len() { + Ok(Handle::new_kv(self.node, self.idx)) + } else { + Err(self) + } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> { + fn insert_fit(&mut self, key: K, val: V) -> *mut V { + // Necessary for correctness, but in a private module + debug_assert!(self.node.len() < CAPACITY); + + unsafe { + slice_insert(self.node.keys_mut(), self.idx, key); + slice_insert(self.node.vals_mut(), self.idx, val); + + self.node.as_leaf_mut().len += 1; + + self.node.vals_mut().get_unchecked_mut(self.idx) + } + } + + pub fn insert(mut self, key: K, val: V) + -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { + + if self.node.len() < CAPACITY { + let ptr = self.insert_fit(key, val); + (InsertResult::Fit(Handle::new_kv(self.node, self.idx)), ptr) + } else { + let middle = Handle::new_kv(self.node, B); + let (mut left, k, v, mut right) = middle.split(); + let ptr = if self.idx <= B { + unsafe { + Handle::new_edge(left.reborrow_mut(), self.idx).insert_fit(key, val) + } + } else { + unsafe { + Handle::new_edge( + right.as_mut().cast_unchecked::<marker::Leaf>(), + self.idx - (B + 1) + ).insert_fit(key, val) + } + }; + (InsertResult::Split(left, k, v, right), ptr) + } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { + fn correct_parent_link(mut self) { + let idx = self.idx as u16; + let ptr = self.node.as_internal_mut() as *mut _; + let mut child = self.descend(); + child.as_leaf_mut().parent = ptr; + child.as_leaf_mut().parent_idx = idx; + } + + unsafe fn cast_unchecked<NewType>(&mut self) + -> Handle<NodeRef<marker::Mut, K, V, NewType>, marker::Edge> { + + Handle::new_edge(self.node.cast_unchecked(), self.idx) + } + + fn insert_fit(&mut self, key: K, val: V, edge: Root<K, V>) { + // Necessary for correctness, but in an internal module + debug_assert!(self.node.len() < CAPACITY); + debug_assert!(edge.height == self.node.height - 1); + + unsafe { + self.cast_unchecked::<marker::Leaf>().insert_fit(key, val); + + slice_insert( + slice::from_raw_parts_mut( + self.node.as_internal_mut().edges.as_mut_ptr(), + self.node.len() + ), + self.idx + 1, + edge.node + ); + + for i in (self.idx+1)..(self.node.len()+1) { + Handle::new_edge(self.node.reborrow_mut(), i).correct_parent_link(); + } + } + } + + pub fn insert(mut self, key: K, val: V, edge: Root<K, V>) + -> InsertResult<'a, K, V, marker::Internal> { + + // Necessary for correctness, but this is an internal module + debug_assert!(edge.height == self.node.height - 1); + + if self.node.len() < CAPACITY { + self.insert_fit(key, val, edge); + InsertResult::Fit(Handle::new_kv(self.node, self.idx)) + } else { + let middle = Handle::new_kv(self.node, B); + let (mut left, k, v, mut right) = middle.split(); + if self.idx <= B { + unsafe { + Handle::new_edge(left.reborrow_mut(), self.idx).insert_fit(key, val, edge); + } + } else { + unsafe { + Handle::new_edge( + right.as_mut().cast_unchecked::<marker::Internal>(), + self.idx - (B + 1) + ).insert_fit(key, val, edge); + } + } + InsertResult::Split(left, k, v, right) + } + } +} + +impl<BorrowType, K, V> + Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge> { + + pub fn descend(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + NodeRef { + height: self.node.height - 1, + node: unsafe { self.node.as_internal().edges.get_unchecked(self.idx).as_ptr() }, + root: self.node.root, + _marker: PhantomData + } + } +} + +impl<'a, K: 'a, V: 'a, NodeType> + Handle<NodeRef<marker::Immut<'a>, K, V, NodeType>, marker::KV> { + + pub fn into_kv(self) -> (&'a K, &'a V) { + let (keys, vals) = self.node.into_slices(); + unsafe { + (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) + } + } +} + +impl<'a, K: 'a, V: 'a, NodeType> + Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> { + + pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) { + let (mut keys, mut vals) = self.node.into_slices_mut(); + unsafe { + (keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx)) + } + } +} + +impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> { + pub fn kv_mut(&mut self) -> (&mut K, &mut V) { + unsafe { + let (mut keys, mut vals) = self.node.reborrow_mut().into_slices_mut(); + (keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx)) + } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> { + pub fn split(mut self) + -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) { + unsafe { + let mut new_node = Box::new(LeafNode::new()); + + let k = ptr::read(self.node.keys().get_unchecked(self.idx)); + let v = ptr::read(self.node.vals().get_unchecked(self.idx)); + + let new_len = self.node.len() - self.idx - 1; + + ptr::copy_nonoverlapping( + self.node.keys().as_ptr().offset(self.idx as isize + 1), + new_node.keys.as_mut_ptr(), + new_len + ); + ptr::copy_nonoverlapping( + self.node.vals().as_ptr().offset(self.idx as isize + 1), + new_node.vals.as_mut_ptr(), + new_len + ); + + self.node.as_leaf_mut().len = self.idx as u16; + new_node.len = new_len as u16; + + ( + self.node, + k, v, + Root { + node: BoxedNode::from_leaf(new_node), + height: 0 + } + ) + } + } + + pub fn remove(mut self) + -> (Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>, K, V) { + unsafe { + let k = slice_remove(self.node.keys_mut(), self.idx); + let v = slice_remove(self.node.vals_mut(), self.idx); + self.node.as_leaf_mut().len -= 1; + (self.left_edge(), k, v) + } + } +} + +impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV> { + pub fn split(mut self) + -> (NodeRef<marker::Mut<'a>, K, V, marker::Internal>, K, V, Root<K, V>) { + unsafe { + let mut new_node = Box::new(InternalNode::new()); + + let k = ptr::read(self.node.keys().get_unchecked(self.idx)); + let v = ptr::read(self.node.vals().get_unchecked(self.idx)); + + let height = self.node.height; + let new_len = self.node.len() - self.idx - 1; + + ptr::copy_nonoverlapping( + self.node.keys().as_ptr().offset(self.idx as isize + 1), + new_node.data.keys.as_mut_ptr(), + new_len + ); + ptr::copy_nonoverlapping( + self.node.vals().as_ptr().offset(self.idx as isize + 1), + new_node.data.vals.as_mut_ptr(), + new_len + ); + ptr::copy_nonoverlapping( + self.node.as_internal().edges.as_ptr().offset(self.idx as isize + 1), + new_node.edges.as_mut_ptr(), + new_len + 1 + ); + + self.node.as_leaf_mut().len = self.idx as u16; + new_node.data.len = new_len as u16; + + let mut new_root = Root { + node: BoxedNode::from_internal(new_node), + height: height + }; + + for i in 0..(new_len+1) { + Handle::new_edge(new_root.as_mut().cast_unchecked(), i).correct_parent_link(); + } + + ( + self.node, + k, v, + new_root + ) + } + } + + pub fn can_merge(&self) -> bool { + ( + self.reborrow() + .left_edge() + .descend() + .len() + + self.reborrow() + .right_edge() + .descend() + .len() + + 1 + ) <= CAPACITY + } + + pub fn merge(mut self) + -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { + let self1 = unsafe { ptr::read(&self) }; + let self2 = unsafe { ptr::read(&self) }; + let mut left_node = self1.left_edge().descend(); + let left_len = left_node.len(); + let mut right_node = self2.right_edge().descend(); + let right_len = right_node.len(); + + // necessary for correctness, but in a private module + debug_assert!(left_len + right_len + 1 <= CAPACITY); + + unsafe { + ptr::write(left_node.keys_mut().get_unchecked_mut(left_len), + slice_remove(self.node.keys_mut(), self.idx)); + ptr::copy_nonoverlapping( + right_node.keys().as_ptr(), + left_node.keys_mut().as_mut_ptr().offset(left_len as isize + 1), + right_len + ); + ptr::write(left_node.vals_mut().get_unchecked_mut(left_len), + slice_remove(self.node.vals_mut(), self.idx)); + ptr::copy_nonoverlapping( + right_node.vals().as_ptr(), + left_node.vals_mut().as_mut_ptr().offset(left_len as isize + 1), + right_len + ); + + slice_remove(&mut self.node.as_internal_mut().edges, self.idx + 1); + for i in self.idx+1..self.node.len() { + Handle::new_edge(self.node.reborrow_mut(), i).correct_parent_link(); + } + self.node.as_leaf_mut().len -= 1; + + left_node.as_leaf_mut().len += right_len as u16 + 1; + + if self.node.height > 1 { + ptr::copy_nonoverlapping( + right_node.cast_unchecked().as_internal().edges.as_ptr(), + left_node.cast_unchecked() + .as_internal_mut() + .edges + .as_mut_ptr() + .offset(left_len as isize + 1), + right_len + 1 + ); + + for i in left_len+1..left_len+right_len+2 { + Handle::new_edge( + left_node.cast_unchecked().reborrow_mut(), + i + ).correct_parent_link(); + } + + heap::deallocate( + *right_node.node as *mut u8, + mem::size_of::<InternalNode<K, V>>(), + mem::align_of::<InternalNode<K, V>>() + ); + } else { + heap::deallocate( + *right_node.node as *mut u8, + mem::size_of::<LeafNode<K, V>>(), + mem::align_of::<LeafNode<K, V>>() + ); + } + + Handle::new_edge(self.node, self.idx) + } + } +} + +impl<BorrowType, K, V, HandleType> + Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, HandleType> { + + pub fn force(self) -> ForceResult< + Handle<NodeRef<BorrowType, K, V, marker::Leaf>, HandleType>, + Handle<NodeRef<BorrowType, K, V, marker::Internal>, HandleType> + > { + match self.node.force() { + ForceResult::Leaf(node) => ForceResult::Leaf(Handle { + node: node, + idx: self.idx, + _marker: PhantomData + }), + ForceResult::Internal(node) => ForceResult::Internal(Handle { + node: node, + idx: self.idx, + _marker: PhantomData + }) + } + } +} + +pub enum ForceResult<Leaf, Internal> { + Leaf(Leaf), + Internal(Internal) +} + +pub enum InsertResult<'a, K, V, Type> { + Fit(Handle<NodeRef<marker::Mut<'a>, K, V, Type>, marker::KV>), + Split(NodeRef<marker::Mut<'a>, K, V, Type>, K, V, Root<K, V>) +} + +pub mod marker { + use core::marker::PhantomData; + + pub enum Leaf { } + pub enum Internal { } + pub enum LeafOrInternal { } + + pub enum Owned { } + pub struct Immut<'a>(PhantomData<&'a ()>); + pub struct Mut<'a>(PhantomData<&'a mut ()>); + + pub enum KV { } + pub enum Edge { } +} + +unsafe fn slice_insert<T>(slice: &mut [T], idx: usize, val: T) { + ptr::copy( + slice.as_ptr().offset(idx as isize), + slice.as_mut_ptr().offset(idx as isize + 1), + slice.len() - idx + ); + ptr::write(slice.get_unchecked_mut(idx), val); +} + +unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T { + let ret = ptr::read(slice.get_unchecked(idx)); + ptr::copy( + slice.as_ptr().offset(idx as isize + 1), + slice.as_mut_ptr().offset(idx as isize), + slice.len() - idx - 1 + ); + ret +} |