@@ -60,12 +60,12 @@ pub const CAPACITY: usize = 2 * B - 1;
60
60
///
61
61
/// See also rust-lang/rfcs#197, which would make this structure significantly more safe by
62
62
/// 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 ) ]
63
68
struct 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
-
69
69
/// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
70
70
/// This either points to an actual node or is null.
71
71
parent : * const InternalNode < K , V > ,
@@ -77,10 +77,14 @@ struct LeafNode<K, V> {
77
77
78
78
/// The number of keys and values this node stores.
79
79
///
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.
83
82
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 ] ,
84
88
}
85
89
86
90
impl < K , V > LeafNode < K , V > {
@@ -97,8 +101,26 @@ impl<K, V> LeafNode<K, V> {
97
101
len : 0
98
102
}
99
103
}
104
+
105
+ fn is_shared_root ( & self ) -> bool {
106
+ self as * const _ == & EMPTY_ROOT_NODE as * const _ as * const LeafNode < K , V >
107
+ }
100
108
}
101
109
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
+
102
124
/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
103
125
/// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an
104
126
/// `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> { }
168
190
unsafe impl < K : Send , V : Send > Send for Root < K , V > { }
169
191
170
192
impl < 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
+
171
208
pub fn new_leaf ( ) -> Self {
172
209
Root {
173
210
node : BoxedNode :: from_leaf ( Box :: new ( unsafe { LeafNode :: new ( ) } ) ) ,
@@ -209,6 +246,7 @@ impl<K, V> Root<K, V> {
209
246
/// new node the root. This increases the height by 1 and is the opposite of `pop_level`.
210
247
pub fn push_level ( & mut self )
211
248
-> NodeRef < marker:: Mut , K , V , marker:: Internal > {
249
+ debug_assert ! ( !self . is_shared_root( ) ) ;
212
250
let mut new_node = Box :: new ( unsafe { InternalNode :: new ( ) } ) ;
213
251
new_node. edges [ 0 ] = unsafe { BoxedNode :: from_ptr ( self . node . as_ptr ( ) ) } ;
214
252
@@ -353,12 +391,16 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
353
391
}
354
392
}
355
393
394
+ pub fn is_shared_root ( & self ) -> bool {
395
+ self . as_leaf ( ) . is_shared_root ( )
396
+ }
397
+
356
398
pub fn keys ( & self ) -> & [ K ] {
357
- self . reborrow ( ) . into_slices ( ) . 0
399
+ self . reborrow ( ) . into_key_slice ( )
358
400
}
359
401
360
- pub fn vals ( & self ) -> & [ V ] {
361
- self . reborrow ( ) . into_slices ( ) . 1
402
+ fn vals ( & self ) -> & [ V ] {
403
+ self . reborrow ( ) . into_val_slice ( )
362
404
}
363
405
364
406
/// 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> {
433
475
marker:: Edge
434
476
>
435
477
> {
478
+ debug_assert ! ( !self . is_shared_root( ) ) ;
436
479
let node = self . node ;
437
480
let ret = self . ascend ( ) . ok ( ) ;
438
481
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> {
500
543
}
501
544
}
502
545
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 ( ) }
505
548
}
506
549
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 ( ) }
509
552
}
510
553
}
511
554
512
555
impl < ' 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 {
516
569
slice:: from_raw_parts (
517
570
self . as_leaf ( ) . keys . as_ptr ( ) ,
518
571
self . len ( )
519
- ) ,
520
- slice:: from_raw_parts (
521
- self . as_leaf ( ) . vals . as_ptr ( ) ,
522
- self . len ( )
523
572
)
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 ( )
524
583
)
525
584
}
526
585
}
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
+ }
527
591
}
528
592
529
593
impl < ' 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> {
535
599
}
536
600
}
537
601
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 {
541
607
slice:: from_raw_parts_mut (
542
608
& mut self . as_leaf_mut ( ) . keys as * mut [ K ] as * mut K ,
543
609
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 ( )
548
610
)
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 ( )
549
621
)
550
622
}
551
623
}
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
+ }
552
629
}
553
630
554
631
impl < ' a , K , V > NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > {
555
632
/// Adds a key/value pair the end of the node.
556
633
pub fn push ( & mut self , key : K , val : V ) {
557
634
// Necessary for correctness, but this is an internal module
558
635
debug_assert ! ( self . len( ) < CAPACITY ) ;
636
+ debug_assert ! ( !self . is_shared_root( ) ) ;
559
637
560
638
let idx = self . len ( ) ;
561
639
@@ -571,6 +649,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
571
649
pub fn push_front ( & mut self , key : K , val : V ) {
572
650
// Necessary for correctness, but this is an internal module
573
651
debug_assert ! ( self . len( ) < CAPACITY ) ;
652
+ debug_assert ! ( !self . is_shared_root( ) ) ;
574
653
575
654
unsafe {
576
655
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
884
963
fn insert_fit ( & mut self , key : K , val : V ) -> * mut V {
885
964
// Necessary for correctness, but in a private module
886
965
debug_assert ! ( self . node. len( ) < CAPACITY ) ;
966
+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
887
967
888
968
unsafe {
889
969
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>
1061
1141
/// allocated node.
1062
1142
pub fn split ( mut self )
1063
1143
-> ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , K , V , Root < K , V > ) {
1144
+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
1064
1145
unsafe {
1065
1146
let mut new_node = Box :: new ( LeafNode :: new ( ) ) ;
1066
1147
@@ -1098,6 +1179,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
1098
1179
/// now adjacent key/value pairs to the left and right of this handle.
1099
1180
pub fn remove ( mut self )
1100
1181
-> ( Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > , K , V ) {
1182
+ debug_assert ! ( !self . node. is_shared_root( ) ) ;
1101
1183
unsafe {
1102
1184
let k = slice_remove ( self . node . keys_mut ( ) , self . idx ) ;
1103
1185
let v = slice_remove ( self . node . vals_mut ( ) , self . idx ) ;
0 commit comments