@@ -67,17 +67,24 @@ struct LeafNode<K, V> {
6767}
6868
6969impl < K , V > LeafNode < K , V > {
70- /// Creates a new `LeafNode`. Unsafe because all nodes should really be hidden behind
70+ /// Initializes a new `LeafNode` in-place.
71+ unsafe fn init ( this : * mut Self ) {
72+ // As a general policy, we leave fields uninitialized if they can be, as this should
73+ // be both slightly faster and easier to track in Valgrind.
74+ unsafe {
75+ // parent_idx, keys, and vals are all MaybeUninit
76+ ( & raw mut ( * this) . parent ) . write ( None ) ;
77+ ( & raw mut ( * this) . len ) . write ( 0 ) ;
78+ }
79+ }
80+
81+ /// Creates a new boxed `LeafNode`. Unsafe because all nodes should really be hidden behind
7182 /// `BoxedNode`, preventing accidental dropping of uninitialized keys and values.
72- unsafe fn new ( ) -> Self {
73- LeafNode {
74- // As a general policy, we leave fields uninitialized if they can be, as this should
75- // be both slightly faster and easier to track in Valgrind.
76- keys : MaybeUninit :: uninit_array ( ) ,
77- vals : MaybeUninit :: uninit_array ( ) ,
78- parent : None ,
79- parent_idx : MaybeUninit :: uninit ( ) ,
80- len : 0 ,
83+ unsafe fn new ( ) -> Box < Self > {
84+ unsafe {
85+ let mut leaf = Box :: new_uninit ( ) ;
86+ LeafNode :: init ( leaf. as_mut_ptr ( ) ) ;
87+ leaf. assume_init ( )
8188 }
8289 }
8390}
@@ -99,15 +106,20 @@ struct InternalNode<K, V> {
99106}
100107
101108impl < K , V > InternalNode < K , V > {
102- /// Creates a new `InternalNode`.
109+ /// Creates a new boxed `InternalNode`.
103110 ///
104- /// This is unsafe for two reasons. First, it returns an `InternalNode` by value , risking
111+ /// This is unsafe for two reasons. First, it returns an owned `InternalNode` in a box , risking
105112 /// dropping of uninitialized fields. Second, an invariant of internal nodes is that `len + 1`
106113 /// edges are initialized and valid, meaning that even when the node is empty (having a
107114 /// `len` of 0), there must be one initialized and valid edge. This function does not set up
108115 /// such an edge.
109- unsafe fn new ( ) -> Self {
110- InternalNode { data : unsafe { LeafNode :: new ( ) } , edges : MaybeUninit :: uninit_array ( ) }
116+ unsafe fn new ( ) -> Box < Self > {
117+ unsafe {
118+ let mut node = Box :: < Self > :: new_uninit ( ) ;
119+ // We only need to initialize the data; the edges are MaybeUninit.
120+ LeafNode :: init ( & raw mut ( * node. as_mut_ptr ( ) ) . data ) ;
121+ node. assume_init ( )
122+ }
111123 }
112124}
113125
@@ -133,7 +145,7 @@ impl<K, V> Root<K, V> {
133145
134146impl < K , V > NodeRef < marker:: Owned , K , V , marker:: Leaf > {
135147 fn new_leaf ( ) -> Self {
136- Self :: from_new_leaf ( Box :: new ( unsafe { LeafNode :: new ( ) } ) )
148+ Self :: from_new_leaf ( unsafe { LeafNode :: new ( ) } )
137149 }
138150
139151 fn from_new_leaf ( leaf : Box < LeafNode < K , V > > ) -> Self {
@@ -143,7 +155,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
143155
144156impl < K , V > NodeRef < marker:: Owned , K , V , marker:: Internal > {
145157 fn new_internal ( child : Root < K , V > ) -> Self {
146- let mut new_node = Box :: new ( unsafe { InternalNode :: new ( ) } ) ;
158+ let mut new_node = unsafe { InternalNode :: new ( ) } ;
147159 new_node. edges [ 0 ] . write ( child. node ) ;
148160 NodeRef :: from_new_internal ( new_node, child. height + 1 )
149161 }
@@ -1075,7 +1087,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
10751087 /// allocated node.
10761088 pub fn split ( mut self ) -> SplitResult < ' a , K , V , marker:: Leaf > {
10771089 unsafe {
1078- let mut new_node = Box :: new ( LeafNode :: new ( ) ) ;
1090+ let mut new_node = LeafNode :: new ( ) ;
10791091
10801092 let kv = self . split_leaf_data ( & mut new_node) ;
10811093
@@ -1110,7 +1122,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
11101122 pub fn split ( mut self ) -> SplitResult < ' a , K , V , marker:: Internal > {
11111123 let old_len = self . node . len ( ) ;
11121124 unsafe {
1113- let mut new_node = Box :: new ( InternalNode :: new ( ) ) ;
1125+ let mut new_node = InternalNode :: new ( ) ;
11141126 let kv = self . split_leaf_data ( & mut new_node. data ) ;
11151127 let new_len = usize:: from ( new_node. data . len ) ;
11161128 move_to_slice (
0 commit comments