// 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 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // This module represents all the internal representation and logic for a B-Tree's node // with a safe interface, so that BTreeMap itself does not depend on any of these details. pub use self::InsertionResult::*; pub use self::SearchResult::*; pub use self::ForceResult::*; pub use self::TraversalItem::*; use core::prelude::*; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp, raw}; use alloc::heap::{self, EMPTY}; use borrow::Borrow; /// Represents the result of an Insertion: either the item fit, or the node had to split pub enum InsertionResult { /// The inserted element fit Fit, /// The inserted element did not fit, so the node was split Split(K, V, Node), } /// Represents the result of a search for a key in a single node pub enum SearchResult { /// The element was found at the given index Found(Handle), /// The element wasn't found, but if it's anywhere, it must be beyond this edge GoDown(Handle), } /// A B-Tree Node. We keep keys/edges/values separate to optimize searching for keys. #[unsafe_no_drop_flag] pub struct Node { // To avoid the need for multiple allocations, we allocate a single buffer with enough space // for `capacity` keys, `capacity` values, and (in internal nodes) `capacity + 1` edges. // Despite this, we store three separate pointers to the three "chunks" of the buffer because // the performance drops significantly if the locations of the vals and edges need to be // recalculated upon access. // // These will never be null during normal usage of a `Node`. However, to avoid the need for a // drop flag, `Node::drop` zeroes `keys`, signaling that the `Node` has already been cleaned // up. keys: Unique, vals: Unique, // In leaf nodes, this will be None, and no space will be allocated for edges. edges: Option>>, // 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. // // Note: instead of accessing this field directly, please call the `len()` method, which should // be more stable in the face of representation changes. _len: usize, // FIXME(gereeter) It shouldn't be necessary to store the capacity in every node, as it should // be constant throughout the tree. Once a solution to this is found, it might be possible to // also pass down the offsets into the buffer that vals and edges are stored at, removing the // need for those two pointers. // // Note: instead of accessing this field directly, please call the `capacity()` method, which // should be more stable in the face of representation changes. _capacity: usize, } struct NodeSlice<'a, K: 'a, V: 'a> { keys: &'a [K], vals: &'a [V], pub edges: &'a [Node], head_is_edge: bool, tail_is_edge: bool, has_edges: bool, } struct MutNodeSlice<'a, K: 'a, V: 'a> { keys: &'a [K], vals: &'a mut [V], pub edges: &'a mut [Node], head_is_edge: bool, tail_is_edge: bool, has_edges: bool, } /// Rounds up to a multiple of a power of two. Returns the closest multiple /// of `target_alignment` that is higher or equal to `unrounded`. /// /// # Panics /// /// Fails if `target_alignment` is not a power of two. #[inline] fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize { assert!(target_alignment.is_power_of_two()); (unrounded + target_alignment - 1) & !(target_alignment - 1) } #[test] fn test_rounding() { assert_eq!(round_up_to_next(0, 4), 0); assert_eq!(round_up_to_next(1, 4), 4); assert_eq!(round_up_to_next(2, 4), 4); assert_eq!(round_up_to_next(3, 4), 4); assert_eq!(round_up_to_next(4, 4), 4); assert_eq!(round_up_to_next(5, 4), 8); } // Returns a tuple of (val_offset, edge_offset), // from the start of a mallocated array. #[inline] fn calculate_offsets(keys_size: usize, vals_size: usize, vals_align: usize, edges_align: usize) -> (usize, usize) { let vals_offset = round_up_to_next(keys_size, vals_align); let end_of_vals = vals_offset + vals_size; let edges_offset = round_up_to_next(end_of_vals, edges_align); (vals_offset, edges_offset) } // Returns a tuple of (minimum required alignment, array_size), // from the start of a mallocated array. #[inline] fn calculate_allocation(keys_size: usize, keys_align: usize, vals_size: usize, vals_align: usize, edges_size: usize, edges_align: usize) -> (usize, usize) { let (_, edges_offset) = calculate_offsets(keys_size, vals_size, vals_align, edges_align); let end_of_edges = edges_offset + edges_size; let min_align = cmp::max(keys_align, cmp::max(vals_align, edges_align)); (min_align, end_of_edges) } #[test] fn test_offset_calculation() { assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 148)); assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 6)); assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 48)); assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144)); assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5)); assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24)); } fn calculate_allocation_generic(capacity: usize, is_leaf: bool) -> (usize, usize) { let (keys_size, keys_align) = (capacity * mem::size_of::(), mem::min_align_of::()); let (vals_size, vals_align) = (capacity * mem::size_of::(), mem::min_align_of::()); let (edges_size, edges_align) = if is_leaf { (0, 1) } else { ((capacity + 1) * mem::size_of::>(), mem::min_align_of::>()) }; calculate_allocation( keys_size, keys_align, vals_size, vals_align, edges_size, edges_align ) } fn calculate_offsets_generic(capacity: usize, is_leaf: bool) -> (usize, usize) { let keys_size = capacity * mem::size_of::(); let vals_size = capacity * mem::size_of::(); let vals_align = mem::min_align_of::(); let edges_align = if is_leaf { 1 } else { mem::min_align_of::>() }; calculate_offsets( keys_size, vals_size, vals_align, edges_align ) } /// An iterator over a slice that owns the elements of the slice but not the allocation. struct RawItems { head: *const T, tail: *const T, } impl RawItems { unsafe fn from_slice(slice: &[T]) -> RawItems { RawItems::from_parts(slice.as_ptr(), slice.len()) } unsafe fn from_parts(ptr: *const T, len: usize) -> RawItems { if mem::size_of::() == 0 { RawItems { head: ptr, tail: (ptr as usize + len) as *const T, } } else { RawItems { head: ptr, tail: ptr.offset(len as isize), } } } unsafe fn push(&mut self, val: T) { ptr::write(self.tail as *mut T, val); if mem::size_of::() == 0 { self.tail = (self.tail as usize + 1) as *const T; } else { self.tail = self.tail.offset(1); } } } impl Iterator for RawItems { type Item = T; fn next(&mut self) -> Option { if self.head == self.tail { None } else { unsafe { let ret = Some(ptr::read(self.head)); if mem::size_of::() == 0 { self.head = (self.head as usize + 1) as *const T; } else { self.head = self.head.offset(1); } ret } } } } impl DoubleEndedIterator for RawItems { fn next_back(&mut self) -> Option { if self.head == self.tail { None } else { unsafe { if mem::size_of::() == 0 { self.tail = (self.tail as usize - 1) as *const T; } else { self.tail = self.tail.offset(-1); } Some(ptr::read(self.tail)) } } } } #[unsafe_destructor] impl Drop for RawItems { fn drop(&mut self) { for _ in self.by_ref() {} } } #[unsafe_destructor] impl Drop for Node { fn drop(&mut self) { if self.keys.is_null() { // 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; } // Do the actual cleanup. unsafe { drop(RawItems::from_slice(self.keys())); drop(RawItems::from_slice(self.vals())); drop(RawItems::from_slice(self.edges())); self.destroy(); } self.keys = unsafe { Unique::new(0 as *mut K) }; } } impl Node { /// Make a new internal node. The caller must initialize the result to fix the invariant that /// there are `len() + 1` edges. unsafe fn new_internal(capacity: usize) -> Node { let (alignment, size) = calculate_allocation_generic::(capacity, false); let buffer = heap::allocate(size, alignment); if buffer.is_null() { ::alloc::oom(); } let (vals_offset, edges_offset) = calculate_offsets_generic::(capacity, false); Node { keys: Unique::new(buffer as *mut K), vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V), edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node)), _len: 0, _capacity: capacity, } } /// Make a new leaf node fn new_leaf(capacity: usize) -> Node { let (alignment, size) = calculate_allocation_generic::(capacity, true); let buffer = unsafe { heap::allocate(size, alignment) }; if buffer.is_null() { ::alloc::oom(); } let (vals_offset, _) = calculate_offsets_generic::(capacity, true); Node { keys: unsafe { Unique::new(buffer as *mut K) }, vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) }, edges: None, _len: 0, _capacity: capacity, } } unsafe fn destroy(&mut self) { let (alignment, size) = calculate_allocation_generic::(self.capacity(), self.is_leaf()); heap::deallocate(*self.keys as *mut u8, size, alignment); } #[inline] pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) { unsafe {( slice::from_raw_parts(*self.keys, self.len()), slice::from_raw_parts(*self.vals, self.len()), )} } #[inline] pub fn as_slices_mut<'a>(&'a mut self) -> (&'a mut [K], &'a mut [V]) { unsafe { mem::transmute(self.as_slices()) } } #[inline] pub fn as_slices_internal<'b>(&'b self) -> NodeSlice<'b, K, V> { let is_leaf = self.is_leaf(); let (keys, vals) = self.as_slices(); let edges: &[_] = if self.is_leaf() { &[] } else { unsafe { let data = match self.edges { None => heap::EMPTY as *const Node, Some(ref p) => **p as *const Node, }; mem::transmute(raw::Slice { data: data, len: self.len() + 1 }) } }; NodeSlice { keys: keys, vals: vals, edges: edges, head_is_edge: true, tail_is_edge: true, has_edges: !is_leaf, } } #[inline] pub fn as_slices_internal_mut<'b>(&'b mut self) -> MutNodeSlice<'b, K, V> { unsafe { mem::transmute(self.as_slices_internal()) } } #[inline] pub fn keys<'a>(&'a self) -> &'a [K] { self.as_slices().0 } #[inline] pub fn keys_mut<'a>(&'a mut self) -> &'a mut [K] { self.as_slices_mut().0 } #[inline] pub fn vals<'a>(&'a self) -> &'a [V] { self.as_slices().1 } #[inline] pub fn vals_mut<'a>(&'a mut self) -> &'a mut [V] { self.as_slices_mut().1 } #[inline] pub fn edges<'a>(&'a self) -> &'a [Node] { self.as_slices_internal().edges } #[inline] pub fn edges_mut<'a>(&'a mut self) -> &'a mut [Node] { self.as_slices_internal_mut().edges } } // FIXME(gereeter) Write an efficient clone_from #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Node { fn clone(&self) -> Node { let mut ret = if self.is_leaf() { Node::new_leaf(self.capacity()) } else { unsafe { Node::new_internal(self.capacity()) } }; unsafe { // For failure safety let mut keys = RawItems::from_parts(ret.keys().as_ptr(), 0); let mut vals = RawItems::from_parts(ret.vals().as_ptr(), 0); let mut edges = RawItems::from_parts(ret.edges().as_ptr(), 0); for key in self.keys() { keys.push(key.clone()) } for val in self.vals() { vals.push(val.clone()) } for edge in self.edges() { edges.push(edge.clone()) } mem::forget(keys); mem::forget(vals); mem::forget(edges); ret._len = self.len(); } ret } } /// A reference to something in the middle of a `Node`. There are two `Type`s of `Handle`s, /// namely `KV` handles, which point to key/value pairs, and `Edge` handles, which point to edges /// before or after key/value pairs. Methods are provided for removing pairs, inserting into edges, /// accessing the stored values, and moving around the `Node`. /// /// This handle is generic, and can take any sort of reference to a `Node`. The reason for this is /// two-fold. First of all, it reduces the amount of repetitive code, implementing functions that /// don't need mutability on both mutable and immutable references. Secondly and more importantly, /// this allows users of the `Handle` API to associate metadata with the reference. This is used in /// `BTreeMap` to give `Node`s temporary "IDs" that persist to when the `Node` is used in a /// `Handle`. /// /// # A note on safety /// /// Unfortunately, the extra power afforded by being generic also means that safety can technically /// be broken. For sensible implementations of `Deref` and `DerefMut`, these handles are perfectly /// safe. As long as repeatedly calling `.deref()` results in the same Node being returned each /// time, everything should work fine. However, if the `Deref` implementation swaps in multiple /// different nodes, then the indices that are assumed to be in bounds suddenly stop being so. For /// example: /// /// ```rust,ignore /// struct Nasty<'a> { /// first: &'a Node, /// second: &'a Node, /// flag: &'a Cell, /// } /// /// impl<'a> Deref for Nasty<'a> { /// type Target = Node; /// /// fn deref(&self) -> &Node { /// if self.flag.get() { /// &*self.second /// } else { /// &*self.first /// } /// } /// } /// /// fn main() { /// let flag = Cell::new(false); /// let mut small_node = Node::make_leaf_root(3); /// let mut large_node = Node::make_leaf_root(100); /// /// for i in 0..100 { /// // Insert to the end /// large_node.edge_handle(i).insert_as_leaf(i, i); /// } /// /// let nasty = Nasty { /// first: &large_node, /// second: &small_node, /// flag: &flag /// } /// /// // The handle points at index 75. /// let handle = Node::search(nasty, 75); /// /// // Now the handle still points at index 75, but on the small node, which has no index 75. /// flag.set(true); /// /// println!("Uninitialized memory: {:?}", handle.into_kv()); /// } /// ``` #[derive(Copy)] pub struct Handle { node: NodeRef, index: usize, marker: PhantomData<(Type, NodeType)>, } pub mod handle { // Handle types. pub enum KV {} pub enum Edge {} // Handle node types. pub enum LeafOrInternal {} pub enum Leaf {} pub enum Internal {} } impl Node { /// Searches for the given key in the node. If it finds an exact match, /// `Found` will be yielded with the matching index. If it doesn't find an exact match, /// `GoDown` will be yielded with the index of the subtree the key must lie in. pub fn search>>(node: NodeRef, key: &Q) -> SearchResult where K: Borrow, Q: Ord { // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V). // For the B configured as of this writing (B = 6), binary search was *significantly* // worse for usizes. match node.as_slices_internal().search_linear(key) { (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }), (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }), } } } // Public interface impl Node { /// Make a leaf root from scratch pub fn make_leaf_root(b: usize) -> Node { Node::new_leaf(capacity_from_b(b)) } /// Make an internal root and swap it with an old root pub fn make_internal_root(left_and_out: &mut Node, b: usize, key: K, value: V, right: Node) { let node = mem::replace(left_and_out, unsafe { Node::new_internal(capacity_from_b(b)) }); left_and_out._len = 1; unsafe { ptr::write(left_and_out.keys_mut().get_unchecked_mut(0), key); ptr::write(left_and_out.vals_mut().get_unchecked_mut(0), value); ptr::write(left_and_out.edges_mut().get_unchecked_mut(0), node); ptr::write(left_and_out.edges_mut().get_unchecked_mut(1), right); } } /// How many key-value pairs the node contains pub fn len(&self) -> usize { self._len } /// How many key-value pairs the node can fit pub fn capacity(&self) -> usize { self._capacity } /// If the node has any children pub fn is_leaf(&self) -> bool { self.edges.is_none() } /// if the node has too few elements pub fn is_underfull(&self) -> bool { self.len() < min_load_from_capacity(self.capacity()) } /// if the node cannot fit any more elements pub fn is_full(&self) -> bool { self.len() == self.capacity() } } impl>, Type, NodeType> Handle { /// Returns a reference to the node that contains the pointed-to edge or key/value pair. This /// is very different from `edge` and `edge_mut` because those return children of the node /// returned by `node`. pub fn node(&self) -> &Node { &*self.node } } impl Handle where NodeRef: Deref> + DerefMut, { /// Converts a handle into one that stores the same information using a raw pointer. This can /// be useful in conjunction with `from_raw` when the type system is insufficient for /// determining the lifetimes of the nodes. pub fn as_raw(&mut self) -> Handle<*mut Node, Type, NodeType> { Handle { node: &mut *self.node as *mut _, index: self.index, marker: PhantomData, } } } impl Handle<*mut Node, Type, NodeType> { /// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle /// stored with a reference. This is an unsafe inverse of `as_raw`, and together they allow /// unsafely extending the lifetime of the reference to the `Node`. pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node, Type, NodeType> { Handle { node: &*self.node, index: self.index, marker: PhantomData, } } /// Converts from a handle stored with a raw pointer, which isn't directly usable, to a handle /// stored with a mutable reference. This is an unsafe inverse of `as_raw`, and together they /// allow unsafely extending the lifetime of the reference to the `Node`. pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node, Type, NodeType> { Handle { node: &mut *self.node, index: self.index, marker: PhantomData, } } } impl<'a, K: 'a, V: 'a> Handle<&'a Node, handle::Edge, handle::Internal> { /// Turns the handle into a reference to the edge it points at. This is necessary because the /// returned pointer has a larger lifetime than what would be returned by `edge` or `edge_mut`, /// making it more suitable for moving down a chain of nodes. pub fn into_edge(self) -> &'a Node { unsafe { self.node.edges().get_unchecked(self.index) } } } impl<'a, K: 'a, V: 'a> Handle<&'a mut Node, handle::Edge, handle::Internal> { /// Turns the handle into a mutable reference to the edge it points at. This is necessary /// because the returned pointer has a larger lifetime than what would be returned by /// `edge_mut`, making it more suitable for moving down a chain of nodes. pub fn into_edge_mut(self) -> &'a mut Node { unsafe { self.node.edges_mut().get_unchecked_mut(self.index) } } } impl>> Handle { // This doesn't exist because there are no uses for it, // but is fine to add, analogous to edge_mut. // // /// Returns a reference to the edge pointed-to by this handle. This should not be // /// confused with `node`, which references the parent node of what is returned here. // pub fn edge(&self) -> &Node } pub enum ForceResult { Leaf(Handle), Internal(Handle) } impl>, Type> Handle { /// Figure out whether this handle is pointing to something in a leaf node or to something in /// an internal node, clarifying the type according to the result. pub fn force(self) -> ForceResult { if self.node.is_leaf() { Leaf(Handle { node: self.node, index: self.index, marker: PhantomData, }) } else { Internal(Handle { node: self.node, index: self.index, marker: PhantomData, }) } } } impl Handle where NodeRef: Deref> + DerefMut, { /// Tries to insert this key-value pair at the given index in this leaf node /// If the node is full, we have to split it. /// /// Returns a *mut V to the inserted value, because the caller may want this when /// they're done mutating the tree, but we don't want to borrow anything for now. pub fn insert_as_leaf(mut self, key: K, value: V) -> (InsertionResult, *mut V) { if !self.node.is_full() { // The element can fit, just insert it (Fit, unsafe { self.node.insert_kv(self.index, key, value) as *mut _ }) } else { // The element can't fit, this node is full. Split it into two nodes. let (new_key, new_val, mut new_right) = self.node.split(); let left_len = self.node.len(); let ptr = unsafe { if self.index <= left_len { self.node.insert_kv(self.index, key, value) } else { // We need to subtract 1 because in splitting we took out new_key and new_val. // Just being in the right node means we are past left_len k/v pairs in the // left node and 1 k/v pair in the parent node. new_right.insert_kv(self.index - left_len - 1, key, value) } } as *mut _; (Split(new_key, new_val, new_right), ptr) } } } impl Handle where NodeRef: Deref> + DerefMut, { /// Returns a mutable reference to the edge pointed-to by this handle. This should not be /// confused with `node`, which references the parent node of what is returned here. pub fn edge_mut(&mut self) -> &mut Node { unsafe { self.node.edges_mut().get_unchecked_mut(self.index) } } /// Tries to insert this key-value pair at the given index in this internal node /// If the node is full, we have to split it. pub fn insert_as_internal(mut self, key: K, value: V, right: Node) -> InsertionResult { if !self.node.is_full() { // The element can fit, just insert it unsafe { self.node.insert_kv(self.index, key, value); self.node.insert_edge(self.index + 1, right); // +1 to insert to the right } Fit } else { // The element can't fit, this node is full. Split it into two nodes. let (new_key, new_val, mut new_right) = self.node.split(); let left_len = self.node.len(); if self.index <= left_len { unsafe { self.node.insert_kv(self.index, key, value); self.node.insert_edge(self.index + 1, right); // +1 to insert to the right } } else { unsafe { // The -1 here is for the same reason as in insert_as_internal - because we // split, there are actually left_len + 1 k/v pairs before the right node, with // the extra 1 being put in the parent. new_right.insert_kv(self.index - left_len - 1, key, value); new_right.insert_edge(self.index - left_len, right); } } Split(new_key, new_val, new_right) } } /// Handle an underflow in this node's child. We favour handling "to the left" because we know /// we're empty, but our neighbour can be full. Handling to the left means when we choose to /// steal, we pop off the end of our neighbour (always fast) and "unshift" ourselves /// (always slow, but at least faster since we know we're half-empty). /// Handling "to the right" reverses these roles. Of course, we merge whenever possible /// because we want dense nodes, and merging is about equal work regardless of direction. pub fn handle_underflow(mut self) { unsafe { if self.index > 0 { self.handle_underflow_to_left(); } else { self.handle_underflow_to_right(); } } } /// Right is underflowed. Tries to steal from left, /// but merges left and right if left is low too. unsafe fn handle_underflow_to_left(&mut self) { let left_len = self.node.edges()[self.index - 1].len(); if left_len > min_load_from_capacity(self.node.capacity()) { self.left_kv().steal_rightward(); } else { self.left_kv().merge_children(); } } /// Left is underflowed. Tries to steal from the right, /// but merges left and right if right is low too. unsafe fn handle_underflow_to_right(&mut self) { let right_len = self.node.edges()[self.index + 1].len(); if right_len > min_load_from_capacity(self.node.capacity()) { self.right_kv().steal_leftward(); } else { self.right_kv().merge_children(); } } } impl Handle where NodeRef: Deref> + DerefMut, { /// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge. /// This is unsafe because the handle might point to the first edge in the node, which has no /// pair to its left. unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, index: self.index - 1, marker: PhantomData, } } /// Gets the handle pointing to the key/value pair just to the right of the pointed-to edge. /// This is unsafe because the handle might point to the last edge in the node, which has no /// pair to its right. unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, index: self.index, marker: PhantomData, } } } impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a Node, handle::KV, NodeType> { /// Turns the handle into references to the key and value it points at. This is necessary /// because the returned pointers have larger lifetimes than what would be returned by `key` /// or `val`. pub fn into_kv(self) -> (&'a K, &'a V) { let (keys, vals) = self.node.as_slices(); unsafe { ( keys.get_unchecked(self.index), vals.get_unchecked(self.index) ) } } } impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node, handle::KV, NodeType> { /// Turns the handle into mutable references to the key and value it points at. This is /// necessary because the returned pointers have larger lifetimes than what would be returned /// by `key_mut` or `val_mut`. pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) { let (keys, vals) = self.node.as_slices_mut(); unsafe { ( keys.get_unchecked_mut(self.index), vals.get_unchecked_mut(self.index) ) } } /// Convert this handle into one pointing at the edge immediately to the left of the key/value /// pair pointed-to by this handle. This is useful because it returns a reference with larger /// lifetime than `left_edge`. pub fn into_left_edge(self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, index: self.index, marker: PhantomData, } } } impl<'a, K: 'a, V: 'a, NodeRef: Deref> + 'a, NodeType> Handle { // These are fine to include, but are currently unneeded. // // /// Returns a reference to the key pointed-to by this handle. This doesn't return a // /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the // /// handle. // pub fn key(&'a self) -> &'a K { // unsafe { self.node.keys().get_unchecked(self.index) } // } // // /// Returns a reference to the value pointed-to by this handle. This doesn't return a // /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the // /// handle. // pub fn val(&'a self) -> &'a V { // unsafe { self.node.vals().get_unchecked(self.index) } // } } impl<'a, K: 'a, V: 'a, NodeRef, NodeType> Handle where NodeRef: 'a + Deref> + DerefMut, { /// Returns a mutable reference to the key pointed-to by this handle. This doesn't return a /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the /// handle. pub fn key_mut(&'a mut self) -> &'a mut K { unsafe { self.node.keys_mut().get_unchecked_mut(self.index) } } /// Returns a mutable reference to the value pointed-to by this handle. This doesn't return a /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the /// handle. pub fn val_mut(&'a mut self) -> &'a mut V { unsafe { self.node.vals_mut().get_unchecked_mut(self.index) } } } impl Handle where NodeRef: Deref> + DerefMut, { /// Gets the handle pointing to the edge immediately to the left of the key/value pair pointed /// to by this handle. pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, index: self.index, marker: PhantomData, } } /// Gets the handle pointing to the edge immediately to the right of the key/value pair pointed /// to by this handle. pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, index: self.index + 1, marker: PhantomData, } } } impl Handle where NodeRef: Deref> + DerefMut, { /// Removes the key/value pair at the handle's location. /// /// # Panics (in debug build) /// /// Panics if the node containing the pair is not a leaf node. pub fn remove_as_leaf(mut self) -> (K, V) { unsafe { self.node.remove_kv(self.index) } } } impl Handle where NodeRef: Deref> + DerefMut { /// Steal! Stealing is roughly analogous to a binary tree rotation. /// In this case, we're "rotating" right. unsafe fn steal_rightward(&mut self) { // Take the biggest stuff off left let (mut key, mut val, edge) = { let mut left_handle = self.left_edge(); let left = left_handle.edge_mut(); let (key, val) = left.pop_kv(); let edge = if left.is_leaf() { None } else { Some(left.pop_edge()) }; (key, val, edge) }; // Swap the parent's separating key-value pair with left's mem::swap(&mut key, self.key_mut()); mem::swap(&mut val, self.val_mut()); // Put them at the start of right let mut right_handle = self.right_edge(); let right = right_handle.edge_mut(); right.insert_kv(0, key, val); match edge { Some(edge) => right.insert_edge(0, edge), None => {} } } /// Steal! Stealing is roughly analogous to a binary tree rotation. /// In this case, we're "rotating" left. unsafe fn steal_leftward(&mut self) { // Take the smallest stuff off right let (mut key, mut val, edge) = { let mut right_handle = self.right_edge(); let right = right_handle.edge_mut(); let (key, val) = right.remove_kv(0); let edge = if right.is_leaf() { None } else { Some(right.remove_edge(0)) }; (key, val, edge) }; // Swap the parent's separating key-value pair with right's mem::swap(&mut key, self.key_mut()); mem::swap(&mut val, self.val_mut()); // Put them at the end of left let mut left_handle = self.left_edge(); let left = left_handle.edge_mut(); left.push_kv(key, val); match edge { Some(edge) => left.push_edge(edge), None => {} } } /// Merge! Smooshes left and right into one node, along with the key-value /// pair that separated them in their parent. unsafe fn merge_children(mut self) { // Permanently remove right's index, and the key-value pair that separates // left and right let (key, val) = self.node.remove_kv(self.index); let right = self.node.remove_edge(self.index + 1); // Give left right's stuff. self.left_edge().edge_mut() .absorb(key, val, right); } } impl Node { /// Returns the mutable handle pointing to the key/value pair at a given index. /// /// # Panics (in debug build) /// /// Panics if the given index is out of bounds. pub fn kv_handle(&mut self, index: usize) -> Handle<&mut Node, handle::KV, handle::LeafOrInternal> { // Necessary for correctness, but in a private module debug_assert!(index < self.len(), "kv_handle index out of bounds"); Handle { node: self, index: index, marker: PhantomData, } } pub fn iter<'a>(&'a self) -> Traversal<'a, K, V> { self.as_slices_internal().iter() } pub fn iter_mut<'a>(&'a mut self) -> MutTraversal<'a, K, V> { self.as_slices_internal_mut().iter_mut() } pub fn into_iter(self) -> MoveTraversal { unsafe { let ret = MoveTraversal { inner: MoveTraversalImpl { keys: RawItems::from_slice(self.keys()), vals: RawItems::from_slice(self.vals()), edges: RawItems::from_slice(self.edges()), ptr: Unique::new(*self.keys as *mut u8), capacity: self.capacity(), is_leaf: self.is_leaf() }, head_is_edge: true, tail_is_edge: true, has_edges: !self.is_leaf(), }; mem::forget(self); ret } } /// When a node has no keys or values and only a single edge, extract that edge. pub fn hoist_lone_child(&mut self) { // Necessary for correctness, but in a private module debug_assert!(self.len() == 0); debug_assert!(!self.is_leaf()); unsafe { let ret = ptr::read(self.edges().get_unchecked(0)); self.destroy(); ptr::write(self, ret); } } } // Vector functions (all unchecked) impl Node { // This must be followed by push_edge on an internal node. #[inline] unsafe fn push_kv(&mut self, key: K, val: V) { let len = self.len(); ptr::write(self.keys_mut().get_unchecked_mut(len), key); ptr::write(self.vals_mut().get_unchecked_mut(len), val); self._len += 1; } // This can only be called immediately after a call to push_kv. #[inline] unsafe fn push_edge(&mut self, edge: Node) { let len = self.len(); ptr::write(self.edges_mut().get_unchecked_mut(len), edge); } // This must be followed by insert_edge on an internal node. #[inline] unsafe fn insert_kv(&mut self, index: usize, key: K, val: V) -> &mut V { ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize + 1), self.keys().as_ptr().offset(index as isize), self.len() - index ); ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize + 1), self.vals().as_ptr().offset(index as isize), self.len() - index ); ptr::write(self.keys_mut().get_unchecked_mut(index), key); ptr::write(self.vals_mut().get_unchecked_mut(index), val); self._len += 1; self.vals_mut().get_unchecked_mut(index) } // This can only be called immediately after a call to insert_kv. #[inline] unsafe fn insert_edge(&mut self, index: usize, edge: Node) { ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize + 1), self.edges().as_ptr().offset(index as isize), self.len() - index ); ptr::write(self.edges_mut().get_unchecked_mut(index), edge); } // This must be followed by pop_edge on an internal node. #[inline] unsafe fn pop_kv(&mut self) -> (K, V) { let key = ptr::read(self.keys().get_unchecked(self.len() - 1)); let val = ptr::read(self.vals().get_unchecked(self.len() - 1)); self._len -= 1; (key, val) } // This can only be called immediately after a call to pop_kv. #[inline] unsafe fn pop_edge(&mut self) -> Node { let edge = ptr::read(self.edges().get_unchecked(self.len() + 1)); edge } // This must be followed by remove_edge on an internal node. #[inline] unsafe fn remove_kv(&mut self, index: usize) -> (K, V) { let key = ptr::read(self.keys().get_unchecked(index)); let val = ptr::read(self.vals().get_unchecked(index)); ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize), self.keys().as_ptr().offset(index as isize + 1), self.len() - index - 1 ); ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize), self.vals().as_ptr().offset(index as isize + 1), self.len() - index - 1 ); self._len -= 1; (key, val) } // This can only be called immediately after a call to remove_kv. #[inline] unsafe fn remove_edge(&mut self, index: usize) -> Node { let edge = ptr::read(self.edges().get_unchecked(index)); ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize), self.edges().as_ptr().offset(index as isize + 1), // index can be == len+1, so do the +1 first to avoid underflow. (self.len() + 1) - index ); edge } } // Private implementation details impl Node { /// Node is full, so split it into two nodes, and yield the middle-most key-value pair /// because we have one too many, and our parent now has one too few fn split(&mut self) -> (K, V, Node) { // Necessary for correctness, but in a private function debug_assert!(self.len() > 0); let mut right = if self.is_leaf() { Node::new_leaf(self.capacity()) } else { unsafe { Node::new_internal(self.capacity()) } }; unsafe { right._len = self.len() / 2; let right_offset = self.len() - right.len(); ptr::copy_nonoverlapping( right.keys_mut().as_mut_ptr(), self.keys().as_ptr().offset(right_offset as isize), right.len() ); ptr::copy_nonoverlapping( right.vals_mut().as_mut_ptr(), self.vals().as_ptr().offset(right_offset as isize), right.len() ); if !self.is_leaf() { ptr::copy_nonoverlapping( right.edges_mut().as_mut_ptr(), self.edges().as_ptr().offset(right_offset as isize), right.len() + 1 ); } let key = ptr::read(self.keys().get_unchecked(right_offset - 1)); let val = ptr::read(self.vals().get_unchecked(right_offset - 1)); self._len = right_offset - 1; (key, val, right) } } /// Take all the values from right, separated by the given key and value fn absorb(&mut self, key: K, val: V, mut right: Node) { // Necessary for correctness, but in a private function // Just as a sanity check, make sure we can fit this guy in debug_assert!(self.len() + right.len() <= self.capacity()); debug_assert!(self.is_leaf() == right.is_leaf()); unsafe { let old_len = self.len(); self._len += right.len() + 1; ptr::write(self.keys_mut().get_unchecked_mut(old_len), key); ptr::write(self.vals_mut().get_unchecked_mut(old_len), val); ptr::copy_nonoverlapping( self.keys_mut().as_mut_ptr().offset(old_len as isize + 1), right.keys().as_ptr(), right.len() ); ptr::copy_nonoverlapping( self.vals_mut().as_mut_ptr().offset(old_len as isize + 1), right.vals().as_ptr(), right.len() ); if !self.is_leaf() { ptr::copy_nonoverlapping( self.edges_mut().as_mut_ptr().offset(old_len as isize + 1), right.edges().as_ptr(), right.len() + 1 ); } right.destroy(); mem::forget(right); } } } /// Get the capacity of a node from the order of the parent B-Tree fn capacity_from_b(b: usize) -> usize { 2 * b - 1 } /// Get the minimum load of a node from its capacity fn min_load_from_capacity(cap: usize) -> usize { // B - 1 cap / 2 } /// A trait for pairs of `Iterator`s, one over edges and the other over key/value pairs. This is /// necessary, as the `MoveTraversalImpl` needs to have a destructor that deallocates the `Node`, /// and a pair of `Iterator`s would require two independent destructors. trait TraversalImpl { type Item; type Edge; fn next_kv(&mut self) -> Option; fn next_kv_back(&mut self) -> Option; fn next_edge(&mut self) -> Option; fn next_edge_back(&mut self) -> Option; } /// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case, /// as no deallocation needs to be done. #[derive(Clone)] struct ElemsAndEdges(Elems, Edges); impl TraversalImpl for ElemsAndEdges where Elems : Iterator, Edges : Iterator { type Item = (K, V); type Edge = E; fn next_kv(&mut self) -> Option<(K, V)> { self.0.next() } fn next_kv_back(&mut self) -> Option<(K, V)> { self.0.next_back() } fn next_edge(&mut self) -> Option { self.1.next() } fn next_edge_back(&mut self) -> Option { self.1.next_back() } } /// A `TraversalImpl` taking a `Node` by value. struct MoveTraversalImpl { keys: RawItems, vals: RawItems, edges: RawItems>, // For deallocation when we are done iterating. ptr: Unique, capacity: usize, is_leaf: bool } unsafe impl Sync for MoveTraversalImpl {} unsafe impl Send for MoveTraversalImpl {} impl TraversalImpl for MoveTraversalImpl { type Item = (K, V); type Edge = Node; fn next_kv(&mut self) -> Option<(K, V)> { match (self.keys.next(), self.vals.next()) { (Some(k), Some(v)) => Some((k, v)), _ => None } } fn next_kv_back(&mut self) -> Option<(K, V)> { match (self.keys.next_back(), self.vals.next_back()) { (Some(k), Some(v)) => Some((k, v)), _ => None } } fn next_edge(&mut self) -> Option> { // Necessary for correctness, but in a private module debug_assert!(!self.is_leaf); self.edges.next() } fn next_edge_back(&mut self) -> Option> { // Necessary for correctness, but in a private module debug_assert!(!self.is_leaf); self.edges.next_back() } } #[unsafe_destructor] impl Drop for MoveTraversalImpl { fn drop(&mut self) { // We need to cleanup the stored values manually, as the RawItems destructor would run // after our deallocation. for _ in self.keys.by_ref() {} for _ in self.vals.by_ref() {} for _ in self.edges.by_ref() {} let (alignment, size) = calculate_allocation_generic::(self.capacity, self.is_leaf); unsafe { heap::deallocate(*self.ptr, size, alignment) }; } } /// An abstraction over all the different kinds of traversals a node supports #[derive(Clone)] struct AbsTraversal { inner: Impl, head_is_edge: bool, tail_is_edge: bool, has_edges: bool, } /// A single atomic step in a traversal. pub enum TraversalItem { /// An element is visited. This isn't written as `Elem(K, V)` just because `opt.map(Elem)` /// requires the function to take a single argument. (Enum constructors are functions.) Elem((K, V)), /// An edge is followed. Edge(E), } /// A traversal over a node's entries and edges pub type Traversal<'a, K, V> = AbsTraversal, slice::Iter<'a, V>>, slice::Iter<'a, Node>>>; /// A mutable traversal over a node's entries and edges pub type MutTraversal<'a, K, V> = AbsTraversal, slice::IterMut<'a, V>>, slice::IterMut<'a, Node>>>; /// An owning traversal over a node's entries and edges pub type MoveTraversal = AbsTraversal>; impl Iterator for AbsTraversal where Impl: TraversalImpl { type Item = TraversalItem; fn next(&mut self) -> Option> { self.next_edge_item().map(Edge).or_else(|| self.next_kv_item().map(Elem) ) } } impl DoubleEndedIterator for AbsTraversal where Impl: TraversalImpl { fn next_back(&mut self) -> Option> { self.next_edge_item_back().map(Edge).or_else(|| self.next_kv_item_back().map(Elem) ) } } impl AbsTraversal where Impl: TraversalImpl { /// Advances the iterator and returns the item if it's an edge. Returns None /// and does nothing if the first item is not an edge. pub fn next_edge_item(&mut self) -> Option { // NB. `&& self.has_edges` might be redundant in this condition. let edge = if self.head_is_edge && self.has_edges { self.inner.next_edge() } else { None }; self.head_is_edge = false; edge } /// Advances the iterator and returns the item if it's an edge. Returns None /// and does nothing if the last item is not an edge. pub fn next_edge_item_back(&mut self) -> Option { let edge = if self.tail_is_edge && self.has_edges { self.inner.next_edge_back() } else { None }; self.tail_is_edge = false; edge } /// Advances the iterator and returns the item if it's a key-value pair. Returns None /// and does nothing if the first item is not a key-value pair. pub fn next_kv_item(&mut self) -> Option<(K, V)> { if !self.head_is_edge { self.head_is_edge = true; self.inner.next_kv() } else { None } } /// Advances the iterator and returns the item if it's a key-value pair. Returns None /// and does nothing if the last item is not a key-value pair. pub fn next_kv_item_back(&mut self) -> Option<(K, V)> { if !self.tail_is_edge { self.tail_is_edge = true; self.inner.next_kv_back() } else { None } } } macro_rules! node_slice_impl { ($NodeSlice:ident, $Traversal:ident, $as_slices_internal:ident, $index:ident, $iter:ident) => { impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> { /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match). fn search_linear(&self, key: &Q) -> (usize, bool) where K: Borrow, Q: Ord { for (i, k) in self.keys.iter().enumerate() { match key.cmp(k.borrow()) { Greater => {}, Equal => return (i, true), Less => return (i, false), } } (self.keys.len(), false) } /// Returns a sub-slice with elements starting with `min_key`. pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> { // _______________ // |_1_|_3_|_5_|_7_| // | | | | | // 0 0 1 1 2 2 3 3 4 index // | | | | | // \___|___|___|___/ slice_from(&0); pos = 0 // \___|___|___/ slice_from(&2); pos = 1 // |___|___|___/ slice_from(&3); pos = 1; result.head_is_edge = false // \___|___/ slice_from(&4); pos = 2 // \___/ slice_from(&6); pos = 3 // \|/ slice_from(&999); pos = 4 let (pos, pos_is_kv) = self.search_linear(min_key); $NodeSlice { has_edges: self.has_edges, edges: if !self.has_edges { self.edges } else { self.edges.$index(pos ..) }, keys: &self.keys[pos ..], vals: self.vals.$index(pos ..), head_is_edge: !pos_is_kv, tail_is_edge: self.tail_is_edge, } } /// Returns a sub-slice with elements up to and including `max_key`. pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> { // _______________ // |_1_|_3_|_5_|_7_| // | | | | | // 0 0 1 1 2 2 3 3 4 index // | | | | | //\|/ | | | | slice_to(&0); pos = 0 // \___/ | | | slice_to(&2); pos = 1 // \___|___| | | slice_to(&3); pos = 1; result.tail_is_edge = false // \___|___/ | | slice_to(&4); pos = 2 // \___|___|___/ | slice_to(&6); pos = 3 // \___|___|___|___/ slice_to(&999); pos = 4 let (pos, pos_is_kv) = self.search_linear(max_key); let pos = pos + if pos_is_kv { 1 } else { 0 }; $NodeSlice { has_edges: self.has_edges, edges: if !self.has_edges { self.edges } else { self.edges.$index(.. (pos + 1)) }, keys: &self.keys[..pos], vals: self.vals.$index(.. pos), head_is_edge: self.head_is_edge, tail_is_edge: !pos_is_kv, } } } impl<'a, K: 'a, V: 'a> $NodeSlice<'a, K, V> { /// Returns an iterator over key/value pairs and edges in a slice. #[inline] pub fn $iter(self) -> $Traversal<'a, K, V> { let mut edges = self.edges.$iter(); // Skip edges at both ends, if excluded. if !self.head_is_edge { edges.next(); } if !self.tail_is_edge { edges.next_back(); } // The key iterator is always immutable. $Traversal { inner: ElemsAndEdges( self.keys.iter().zip(self.vals.$iter()), edges ), head_is_edge: self.head_is_edge, tail_is_edge: self.tail_is_edge, has_edges: self.has_edges, } } } } } node_slice_impl!(NodeSlice, Traversal, as_slices_internal, index, iter); node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, index_mut, iter_mut);