@@ -60,12 +60,12 @@ pub const CAPACITY: usize = 2 * B - 1;
6060///
6161/// See also rust-lang/rfcs#197, which would make this structure significantly more safe by
6262/// avoiding accidentally dropping unused and uninitialized keys and values.
63+ ///
64+ /// We put the metadata first so that its position is the same for every `K` and `V`, in order
65+ /// to statically allocate a single dummy node to avoid allocations. This struct is `repr(C)` to
66+ /// prevent them from being reordered.
67+ #[ repr( C ) ]
6368struct LeafNode < K , V > {
64- /// The arrays storing the actual data of the node. Only the first `len` elements of each
65- /// array are initialized and valid.
66- keys : [ K ; CAPACITY ] ,
67- vals : [ V ; CAPACITY ] ,
68-
6969 /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
7070 /// This either points to an actual node or is null.
7171 parent : * const InternalNode < K , V > ,
@@ -77,10 +77,14 @@ struct LeafNode<K, V> {
7777
7878 /// The number of keys and values this node stores.
7979 ///
80- /// This is at the end of the node's representation and next to `parent_idx` to encourage
81- /// the compiler to join `len` and `parent_idx` into the same 32-bit word, reducing space
82- /// overhead.
80+ /// This next to `parent_idx` to encourage the compiler to join `len` and
81+ /// `parent_idx` into the same 32-bit word, reducing space overhead.
8382 len : u16 ,
83+
84+ /// The arrays storing the actual data of the node. Only the first `len` elements of each
85+ /// array are initialized and valid.
86+ keys : [ K ; CAPACITY ] ,
87+ vals : [ V ; CAPACITY ] ,
8488}
8589
8690impl < K , V > LeafNode < K , V > {
@@ -97,8 +101,26 @@ impl<K, V> LeafNode<K, V> {
97101 len : 0
98102 }
99103 }
104+
105+ fn is_shared_root ( & self ) -> bool {
106+ self as * const _ == & EMPTY_ROOT_NODE as * const _ as * const LeafNode < K , V >
107+ }
100108}
101109
110+ // We need to implement Sync here in order to make a static instance.
111+ unsafe impl Sync for LeafNode < ( ) , ( ) > { }
112+
113+ // An empty node used as a placeholder for the root node, to avoid allocations.
114+ // We use () in order to save space, since no operation on an empty tree will
115+ // ever take a pointer past the first key.
116+ static EMPTY_ROOT_NODE : LeafNode < ( ) , ( ) > = LeafNode {
117+ parent : ptr:: null ( ) ,
118+ parent_idx : 0 ,
119+ len : 0 ,
120+ keys : [ ( ) ; CAPACITY ] ,
121+ vals : [ ( ) ; CAPACITY ] ,
122+ } ;
123+
102124/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
103125/// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an
104126/// `InternalNode` can be directly casted to a pointer to the underlying `LeafNode` portion of the
@@ -168,6 +190,21 @@ unsafe impl<K: Sync, V: Sync> Sync for Root<K, V> { }
168190unsafe impl < K : Send , V : Send > Send for Root < K , V > { }
169191
170192impl < K , V > Root < K , V > {
193+ pub fn is_shared_root ( & self ) -> bool {
194+ self . as_ref ( ) . is_shared_root ( )
195+ }
196+
197+ pub fn shared_empty_root ( ) -> Self {
198+ Root {
199+ node : unsafe {
200+ BoxedNode :: from_ptr ( NonNull :: new_unchecked (
201+ & EMPTY_ROOT_NODE as * const _ as * const LeafNode < K , V > as * mut _
202+ ) )
203+ } ,
204+ height : 0 ,
205+ }
206+ }
207+
171208 pub fn new_leaf ( ) -> Self {
172209 Root {
173210 node : BoxedNode :: from_leaf ( Box :: new ( unsafe { LeafNode :: new ( ) } ) ) ,
@@ -209,6 +246,7 @@ impl<K, V> Root<K, V> {
209246 /// new node the root. This increases the height by 1 and is the opposite of `pop_level`.
210247 pub fn push_level ( & mut self )
211248 -> NodeRef < marker:: Mut , K , V , marker:: Internal > {
249+ debug_assert ! ( !self . is_shared_root( ) ) ;
212250 let mut new_node = Box :: new ( unsafe { InternalNode :: new ( ) } ) ;
213251 new_node. edges [ 0 ] = unsafe { BoxedNode :: from_ptr ( self . node . as_ptr ( ) ) } ;
214252
@@ -353,12 +391,16 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
353391 }
354392 }
355393
394+ pub fn is_shared_root ( & self ) -> bool {
395+ self . as_leaf ( ) . is_shared_root ( )
396+ }
397+
356398 pub fn keys ( & self ) -> & [ K ] {
357- self . reborrow ( ) . into_slices ( ) . 0
399+ self . reborrow ( ) . into_key_slice ( )
358400 }
359401
360- pub fn vals ( & self ) -> & [ V ] {
361- self . reborrow ( ) . into_slices ( ) . 1
402+ fn vals ( & self ) -> & [ V ] {
403+ self . reborrow ( ) . into_val_slice ( )
362404 }
363405
364406 /// Finds the parent of the current node. Returns `Ok(handle)` if the current
@@ -433,6 +475,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
433475 marker:: Edge
434476 >
435477 > {
478+ debug_assert ! ( !self . is_shared_root( ) ) ;
436479 let node = self . node ;
437480 let ret = self . ascend ( ) . ok ( ) ;
438481 Global . dealloc ( node. as_opaque ( ) , Layout :: new :: < LeafNode < K , V > > ( ) ) ;
@@ -500,30 +543,51 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
500543 }
501544 }
502545
503- pub fn keys_mut ( & mut self ) -> & mut [ K ] {
504- unsafe { self . reborrow_mut ( ) . into_slices_mut ( ) . 0 }
546+ fn keys_mut ( & mut self ) -> & mut [ K ] {
547+ unsafe { self . reborrow_mut ( ) . into_key_slice_mut ( ) }
505548 }
506549
507- pub fn vals_mut ( & mut self ) -> & mut [ V ] {
508- unsafe { self . reborrow_mut ( ) . into_slices_mut ( ) . 1 }
550+ fn vals_mut ( & mut self ) -> & mut [ V ] {
551+ unsafe { self . reborrow_mut ( ) . into_val_slice_mut ( ) }
509552 }
510553}
511554
512555impl < ' a , K : ' a , V : ' a , Type > NodeRef < marker:: Immut < ' a > , K , V , Type > {
513- pub fn into_slices ( self ) -> ( & ' a [ K ] , & ' a [ V ] ) {
514- unsafe {
515- (
556+ fn into_key_slice ( self ) -> & ' a [ K ] {
557+ // When taking a pointer to the keys, if our key has a stricter
558+ // alignment requirement than the shared root does, then the pointer
559+ // would be out of bounds, which LLVM assumes will not happen. If the
560+ // alignment is more strict, we need to make an empty slice that doesn't
561+ // use an out of bounds pointer.
562+ if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
563+ & [ ]
564+ } else {
565+ // Here either it's not the root, or the alignment is less strict,
566+ // in which case the keys pointer will point "one-past-the-end" of
567+ // the node, which is allowed by LLVM.
568+ unsafe {
516569 slice:: from_raw_parts (
517570 self . as_leaf ( ) . keys . as_ptr ( ) ,
518571 self . len ( )
519- ) ,
520- slice:: from_raw_parts (
521- self . as_leaf ( ) . vals . as_ptr ( ) ,
522- self . len ( )
523572 )
573+ }
574+ }
575+ }
576+
577+ fn into_val_slice ( self ) -> & ' a [ V ] {
578+ debug_assert ! ( !self . is_shared_root( ) ) ;
579+ unsafe {
580+ slice:: from_raw_parts (
581+ self . as_leaf ( ) . vals . as_ptr ( ) ,
582+ self . len ( )
524583 )
525584 }
526585 }
586+
587+ fn into_slices ( self ) -> ( & ' a [ K ] , & ' a [ V ] ) {
588+ let k = unsafe { ptr:: read ( & self ) } ;
589+ ( k. into_key_slice ( ) , self . into_val_slice ( ) )
590+ }
527591}
528592
529593impl < ' a , K : ' a , V : ' a , Type > NodeRef < marker:: Mut < ' a > , K , V , Type > {
@@ -535,27 +599,41 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
535599 }
536600 }
537601
538- pub fn into_slices_mut ( mut self ) -> ( & ' a mut [ K ] , & ' a mut [ V ] ) {
539- unsafe {
540- (
602+ fn into_key_slice_mut ( mut self ) -> & ' a mut [ K ] {
603+ if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
604+ & mut [ ]
605+ } else {
606+ unsafe {
541607 slice:: from_raw_parts_mut (
542608 & mut self . as_leaf_mut ( ) . keys as * mut [ K ] as * mut K ,
543609 self . len ( )
544- ) ,
545- slice:: from_raw_parts_mut (
546- & mut self . as_leaf_mut ( ) . vals as * mut [ V ] as * mut V ,
547- self . len ( )
548610 )
611+ }
612+ }
613+ }
614+
615+ fn into_val_slice_mut ( mut self ) -> & ' a mut [ V ] {
616+ debug_assert ! ( !self . is_shared_root( ) ) ;
617+ unsafe {
618+ slice:: from_raw_parts_mut (
619+ & mut self . as_leaf_mut ( ) . vals as * mut [ V ] as * mut V ,
620+ self . len ( )
549621 )
550622 }
551623 }
624+
625+ fn into_slices_mut ( self ) -> ( & ' a mut [ K ] , & ' a mut [ V ] ) {
626+ let k = unsafe { ptr:: read ( & self ) } ;
627+ ( k. into_key_slice_mut ( ) , self . into_val_slice_mut ( ) )
628+ }
552629}
553630
554631impl < ' a , K , V > NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > {
555632 /// Adds a key/value pair the end of the node.
556633 pub fn push ( & mut self , key : K , val : V ) {
557634 // Necessary for correctness, but this is an internal module
558635 debug_assert ! ( self . len( ) < CAPACITY ) ;
636+ debug_assert ! ( !self . is_shared_root( ) ) ;
559637
560638 let idx = self . len ( ) ;
561639
@@ -571,6 +649,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
571649 pub fn push_front ( & mut self , key : K , val : V ) {
572650 // Necessary for correctness, but this is an internal module
573651 debug_assert ! ( self . len( ) < CAPACITY ) ;
652+ debug_assert ! ( !self . is_shared_root( ) ) ;
574653
575654 unsafe {
576655 slice_insert ( self . keys_mut ( ) , 0 , key) ;
@@ -884,6 +963,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
884963 fn insert_fit ( & mut self , key : K , val : V ) -> * mut V {
885964 // Necessary for correctness, but in a private module
886965 debug_assert ! ( self . node. len( ) < CAPACITY ) ;
966+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
887967
888968 unsafe {
889969 slice_insert ( self . node . keys_mut ( ) , self . idx , key) ;
@@ -1061,6 +1141,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
10611141 /// allocated node.
10621142 pub fn split ( mut self )
10631143 -> ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , K , V , Root < K , V > ) {
1144+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
10641145 unsafe {
10651146 let mut new_node = Box :: new ( LeafNode :: new ( ) ) ;
10661147
@@ -1098,6 +1179,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
10981179 /// now adjacent key/value pairs to the left and right of this handle.
10991180 pub fn remove ( mut self )
11001181 -> ( Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > , K , V ) {
1182+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
11011183 unsafe {
11021184 let k = slice_remove ( self . node . keys_mut ( ) , self . idx ) ;
11031185 let v = slice_remove ( self . node . vals_mut ( ) , self . idx ) ;
0 commit comments