diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2020-03-18 11:10:21 -0400 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2020-03-20 09:43:41 -0400 |
| commit | 54b7c38889ee7bb59f4d6449822fcfdfa3448ddb (patch) | |
| tree | 20f091fbeaf9f042cb696cc0c4b06dd819f2ec65 /src | |
| parent | 3c04fda751352fe00884782e7adf792a5e2a91c4 (diff) | |
| download | rust-54b7c38889ee7bb59f4d6449822fcfdfa3448ddb.tar.gz rust-54b7c38889ee7bb59f4d6449822fcfdfa3448ddb.zip | |
Drop NodeHeader type from BTree code
We no longer have a separate header because the shared root is gone; all code can work solely with leafs now.
Diffstat (limited to 'src')
| -rw-r--r-- | src/liballoc/collections/btree/node.rs | 46 |
1 files changed, 5 insertions, 41 deletions
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 99f531264ba..6ebb98c42cd 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -44,34 +44,7 @@ const B: usize = 6; pub const MIN_LEN: usize = B - 1; pub const CAPACITY: usize = 2 * B - 1; -/// The underlying representation of leaf nodes. Note that it is often unsafe to actually store -/// these, since only the first `len` keys and values are assumed to be initialized. As such, -/// these should always be put behind pointers, and specifically behind `BoxedNode` in the owned -/// case. -/// -/// We have a separate type for the header and rely on it matching the prefix of `LeafNode`, in -/// order to statically allocate a single dummy node to avoid allocations. This struct is -/// `repr(C)` to prevent them from being reordered. `LeafNode` does not just contain a -/// `NodeHeader` because we do not want unnecessary padding between `len` and the keys. -/// Crucially, `NodeHeader` can be safely transmuted to different K and V. (This is exploited -/// by `as_header`.) -#[repr(C)] -struct NodeHeader<K, V> { - /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`. - /// This either points to an actual node or is null. - parent: *const InternalNode<K, V>, - - /// This node's index into the parent node's `edges` array. - /// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`. - /// This is only guaranteed to be initialized when `parent` is non-null. - parent_idx: MaybeUninit<u16>, - - /// The number of keys and values this node stores. - /// - /// This next to `parent_idx` to encourage the compiler to join `len` and - /// `parent_idx` into the same 32-bit word, reducing space overhead. - len: u16, -} +/// The underlying representation of leaf nodes. #[repr(C)] struct LeafNode<K, V> { /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`. @@ -141,10 +114,7 @@ impl<K, V> InternalNode<K, V> { /// A managed, non-null pointer to a node. This is either an owned pointer to /// `LeafNode<K, V>` or an owned pointer to `InternalNode<K, V>`. /// -/// All of these types have a `NodeHeader<K, V>` prefix, meaning that they have at -/// least the same size as `NodeHeader<K, V>` and store the same kinds of data at the same -/// offsets; and they have a pointer alignment at least as large as `NodeHeader<K, V>`'s. -/// However, `BoxedNode` contains no information as to which of the three types +/// However, `BoxedNode` contains no information as to which of the two types /// of nodes it actually contains, and, partially due to this lack of information, /// has no destructor. struct BoxedNode<K, V> { @@ -279,8 +249,6 @@ impl<K, V> Root<K, V> { /// `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. -/// -/// Turning this into a `NodeHeader` reference is always safe. pub struct NodeRef<BorrowType, K, V, Type> { /// The number of levels below the node. height: usize, @@ -322,7 +290,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { /// Note that, despite being safe, calling this function can have the side effect /// of invalidating mutable references that unsafe code has created. pub fn len(&self) -> usize { - self.as_header().len as usize + self.as_leaf().len as usize } /// Returns the height of this node in the whole tree. Zero height denotes the @@ -353,10 +321,6 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { unsafe { self.node.as_ref() } } - fn as_header(&self) -> &NodeHeader<K, V> { - unsafe { &*(self.node.as_ptr() as *const NodeHeader<K, V>) } - } - /// Borrows a view into the keys stored in the node. pub fn keys(&self) -> &[K] { self.reborrow().into_key_slice() @@ -377,7 +341,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { pub fn ascend( self, ) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> { - let parent_as_leaf = self.as_header().parent as *const LeafNode<K, V>; + let parent_as_leaf = self.as_leaf().parent as *const LeafNode<K, V>; if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { Ok(Handle { node: NodeRef { @@ -386,7 +350,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { root: self.root, _marker: PhantomData, }, - idx: unsafe { usize::from(*self.as_header().parent_idx.as_ptr()) }, + idx: unsafe { usize::from(*self.as_leaf().parent_idx.as_ptr()) }, _marker: PhantomData, }) } else { |
