Fallout: port btree to use Unique, some markers.
This commit is contained in:
parent
b3c00a69f2
commit
68ebe640b6
@ -21,10 +21,11 @@
|
|||||||
use core::borrow::BorrowFrom;
|
use core::borrow::BorrowFrom;
|
||||||
use core::cmp::Ordering::{Greater, Less, Equal};
|
use core::cmp::Ordering::{Greater, Less, Equal};
|
||||||
use core::iter::Zip;
|
use core::iter::Zip;
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::ops::{Deref, DerefMut, Index, IndexMut};
|
use core::ops::{Deref, DerefMut, Index, IndexMut};
|
||||||
use core::ptr::Unique;
|
use core::ptr::Unique;
|
||||||
use core::{slice, mem, ptr, cmp, num, raw};
|
use core::{slice, mem, ptr, cmp, num, raw};
|
||||||
use alloc::heap;
|
use alloc::heap::{self, EMPTY};
|
||||||
|
|
||||||
/// Represents the result of an Insertion: either the item fit, or the node had to split
|
/// Represents the result of an Insertion: either the item fit, or the node had to split
|
||||||
pub enum InsertionResult<K, V> {
|
pub enum InsertionResult<K, V> {
|
||||||
@ -57,8 +58,8 @@ pub struct Node<K, V> {
|
|||||||
keys: Unique<K>,
|
keys: Unique<K>,
|
||||||
vals: Unique<V>,
|
vals: Unique<V>,
|
||||||
|
|
||||||
// In leaf nodes, this will be null, and no space will be allocated for edges.
|
// In leaf nodes, this will be None, and no space will be allocated for edges.
|
||||||
edges: Unique<Node<K, V>>,
|
edges: Option<Unique<Node<K, V>>>,
|
||||||
|
|
||||||
// At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
|
// At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
|
||||||
// `_len + 1` edges. In a leaf node, there will never be any edges.
|
// `_len + 1` edges. In a leaf node, there will never be any edges.
|
||||||
@ -278,8 +279,11 @@ fn drop(&mut self) {
|
|||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
impl<K, V> Drop for Node<K, V> {
|
impl<K, V> Drop for Node<K, V> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.keys.ptr.is_null() {
|
if self.keys.is_null() {
|
||||||
// We have already cleaned up this node.
|
// Since we have #[unsafe_no_drop_flag], we have to watch
|
||||||
|
// out for a null value being stored in self.keys. (Using
|
||||||
|
// null is technically a violation of the `Unique`
|
||||||
|
// requirements, though.)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +296,7 @@ fn drop(&mut self) {
|
|||||||
self.destroy();
|
self.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.keys.ptr = ptr::null_mut();
|
self.keys = unsafe { Unique::new(0 as *mut K) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,9 +312,9 @@ unsafe fn new_internal(capacity: usize) -> Node<K, V> {
|
|||||||
let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
|
let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
keys: Unique(buffer as *mut K),
|
keys: Unique::new(buffer as *mut K),
|
||||||
vals: Unique(buffer.offset(vals_offset as isize) as *mut V),
|
vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V),
|
||||||
edges: Unique(buffer.offset(edges_offset as isize) as *mut Node<K, V>),
|
edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node<K, V>)),
|
||||||
_len: 0,
|
_len: 0,
|
||||||
_capacity: capacity,
|
_capacity: capacity,
|
||||||
}
|
}
|
||||||
@ -326,9 +330,9 @@ fn new_leaf(capacity: usize) -> Node<K, V> {
|
|||||||
let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
|
let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
keys: Unique(buffer as *mut K),
|
keys: unsafe { Unique::new(buffer as *mut K) },
|
||||||
vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }),
|
vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) },
|
||||||
edges: Unique(ptr::null_mut()),
|
edges: None,
|
||||||
_len: 0,
|
_len: 0,
|
||||||
_capacity: capacity,
|
_capacity: capacity,
|
||||||
}
|
}
|
||||||
@ -337,18 +341,18 @@ fn new_leaf(capacity: usize) -> Node<K, V> {
|
|||||||
unsafe fn destroy(&mut self) {
|
unsafe fn destroy(&mut self) {
|
||||||
let (alignment, size) =
|
let (alignment, size) =
|
||||||
calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
|
calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
|
||||||
heap::deallocate(self.keys.ptr as *mut u8, size, alignment);
|
heap::deallocate(*self.keys as *mut u8, size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
|
pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
|
||||||
unsafe {(
|
unsafe {(
|
||||||
mem::transmute(raw::Slice {
|
mem::transmute(raw::Slice {
|
||||||
data: self.keys.ptr,
|
data: *self.keys as *const K,
|
||||||
len: self.len()
|
len: self.len()
|
||||||
}),
|
}),
|
||||||
mem::transmute(raw::Slice {
|
mem::transmute(raw::Slice {
|
||||||
data: self.vals.ptr,
|
data: *self.vals as *const V,
|
||||||
len: self.len()
|
len: self.len()
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
@ -367,8 +371,12 @@ pub fn as_slices_internal<'b>(&'b self) -> NodeSlice<'b, K, V> {
|
|||||||
&[]
|
&[]
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let data = match self.edges {
|
||||||
|
None => heap::EMPTY as *const Node<K,V>,
|
||||||
|
Some(ref p) => **p as *const Node<K,V>,
|
||||||
|
};
|
||||||
mem::transmute(raw::Slice {
|
mem::transmute(raw::Slice {
|
||||||
data: self.edges.ptr,
|
data: data,
|
||||||
len: self.len() + 1
|
len: self.len() + 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -524,7 +532,8 @@ fn clone(&self) -> Node<K, V> {
|
|||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct Handle<NodeRef, Type, NodeType> {
|
pub struct Handle<NodeRef, Type, NodeType> {
|
||||||
node: NodeRef,
|
node: NodeRef,
|
||||||
index: usize
|
index: usize,
|
||||||
|
marker: PhantomData<(Type, NodeType)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod handle {
|
pub mod handle {
|
||||||
@ -548,8 +557,8 @@ pub fn search<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key:
|
|||||||
// For the B configured as of this writing (B = 6), binary search was *significantly*
|
// For the B configured as of this writing (B = 6), binary search was *significantly*
|
||||||
// worse for usizes.
|
// worse for usizes.
|
||||||
match node.as_slices_internal().search_linear(key) {
|
match node.as_slices_internal().search_linear(key) {
|
||||||
(index, true) => Found(Handle { node: node, index: index }),
|
(index, true) => Found(Handle { node: node, index: index, marker: PhantomData }),
|
||||||
(index, false) => GoDown(Handle { node: node, index: index }),
|
(index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,7 +595,7 @@ pub fn capacity(&self) -> usize {
|
|||||||
|
|
||||||
/// If the node has any children
|
/// If the node has any children
|
||||||
pub fn is_leaf(&self) -> bool {
|
pub fn is_leaf(&self) -> bool {
|
||||||
self.edges.ptr.is_null()
|
self.edges.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if the node has too few elements
|
/// if the node has too few elements
|
||||||
@ -618,7 +627,8 @@ impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where
|
|||||||
pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
|
pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node as *mut _,
|
node: &mut *self.node as *mut _,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +640,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
|
|||||||
pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
|
pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &*self.node,
|
node: &*self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +651,8 @@ pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
|
|||||||
pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
|
pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -688,12 +700,14 @@ pub fn force(self) -> ForceResult<NodeRef, Type> {
|
|||||||
if self.node.is_leaf() {
|
if self.node.is_leaf() {
|
||||||
Leaf(Handle {
|
Leaf(Handle {
|
||||||
node: self.node,
|
node: self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Internal(Handle {
|
Internal(Handle {
|
||||||
node: self.node,
|
node: self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,7 +840,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
|
|||||||
unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
|
unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index - 1
|
index: self.index - 1,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +851,8 @@ unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, No
|
|||||||
unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
|
unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -876,7 +892,8 @@ pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
|
|||||||
pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,7 +943,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
|
|||||||
pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index
|
index: self.index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +953,8 @@ pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, N
|
|||||||
pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
|
||||||
Handle {
|
Handle {
|
||||||
node: &mut *self.node,
|
node: &mut *self.node,
|
||||||
index: self.index + 1
|
index: self.index + 1,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,7 +1063,8 @@ pub fn kv_handle(&mut self, index: usize) -> Handle<&mut Node<K, V>, handle::KV,
|
|||||||
debug_assert!(index < self.len(), "kv_handle index out of bounds");
|
debug_assert!(index < self.len(), "kv_handle index out of bounds");
|
||||||
Handle {
|
Handle {
|
||||||
node: self,
|
node: self,
|
||||||
index: index
|
index: index,
|
||||||
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1064,7 +1084,7 @@ pub fn into_iter(self) -> MoveTraversal<K, V> {
|
|||||||
vals: RawItems::from_slice(self.vals()),
|
vals: RawItems::from_slice(self.vals()),
|
||||||
edges: RawItems::from_slice(self.edges()),
|
edges: RawItems::from_slice(self.edges()),
|
||||||
|
|
||||||
ptr: self.keys.ptr as *mut u8,
|
ptr: *self.keys as *mut u8,
|
||||||
capacity: self.capacity(),
|
capacity: self.capacity(),
|
||||||
is_leaf: self.is_leaf()
|
is_leaf: self.is_leaf()
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user