about summary refs log tree commit diff
diff options
context:
space:
mode:
authorC Jones <code@calebjones.net>2018-05-01 15:26:49 -0400
committerC Jones <code@calebjones.net>2018-05-07 22:14:34 -0400
commit5b94e9f053c3fecb0e29c89e453ecaf07d97218c (patch)
tree7436f0906cfcd11722cc843fee28606463f44aca
parentfa62eba92ad9a3d25b200835a5cd3ca48b700d75 (diff)
downloadrust-5b94e9f053c3fecb0e29c89e453ecaf07d97218c.tar.gz
rust-5b94e9f053c3fecb0e29c89e453ecaf07d97218c.zip
Split into_slices() to avoid making extra slices
This splits into_slices() into into_key_slice() and into_val_slice(). While the
extra calls would get optimized out, this is a useful semantic change since we
call keys() while iterating, and we don't want to construct and out-of-bounds
val() pointer in the process if we happen to be pointing to the shared static
root.

This also paves the way for doing the alignment handling conditional differently
for the keys and values.
-rw-r--r--src/liballoc/btree/node.rs66
1 files changed, 41 insertions, 25 deletions
diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs
index 79615e11c67..4dcc4d54eaf 100644
--- a/src/liballoc/btree/node.rs
+++ b/src/liballoc/btree/node.rs
@@ -393,11 +393,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     }
 
     pub fn keys(&self) -> &[K] {
-        self.reborrow().into_slices().0
+        self.reborrow().into_key_slice()
     }
 
-    pub fn vals(&self) -> &[V] {
-        self.reborrow().into_slices().1
+    fn vals(&self) -> &[V] {
+        self.reborrow().into_val_slice()
     }
 
     /// Finds the parent of the current node. Returns `Ok(handle)` if the current
@@ -540,29 +540,37 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     }
 
     pub fn keys_mut(&mut self) -> &mut [K] {
-        unsafe { self.reborrow_mut().into_slices_mut().0 }
+        unsafe { self.reborrow_mut().into_key_slice_mut() }
     }
 
     pub fn vals_mut(&mut self) -> &mut [V] {
-        unsafe { self.reborrow_mut().into_slices_mut().1 }
+        unsafe { self.reborrow_mut().into_val_slice_mut() }
     }
 }
 
 impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
-    pub fn into_slices(self) -> (&'a [K], &'a [V]) {
+    fn into_key_slice(self) -> &'a [K] {
         unsafe {
-            (
-                slice::from_raw_parts(
-                    self.as_leaf().keys.as_ptr(),
-                    self.len()
-                ),
-                slice::from_raw_parts(
-                    self.as_leaf().vals.as_ptr(),
-                    self.len()
-                )
+            slice::from_raw_parts(
+                self.as_leaf().keys.as_ptr(),
+                self.len()
+            )
+        }
+    }
+
+    fn into_val_slice(self) -> &'a [V] {
+        unsafe {
+            slice::from_raw_parts(
+                self.as_leaf().vals.as_ptr(),
+                self.len()
             )
         }
     }
+
+    fn into_slices(self) -> (&'a [K], &'a [V]) {
+        let k = unsafe { ptr::read(&self) };
+        (k.into_key_slice(), self.into_val_slice())
+    }
 }
 
 impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
@@ -574,20 +582,28 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
         }
     }
 
-    pub fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) {
+    fn into_key_slice_mut(mut self) -> &'a mut [K] {
         unsafe {
-            (
-                slice::from_raw_parts_mut(
-                    &mut self.as_leaf_mut().keys as *mut [K] as *mut K,
-                    self.len()
-                ),
-                slice::from_raw_parts_mut(
-                    &mut self.as_leaf_mut().vals as *mut [V] as *mut V,
-                    self.len()
-                )
+            slice::from_raw_parts_mut(
+                &mut self.as_leaf_mut().keys as *mut [K] as *mut K,
+                self.len()
+            )
+        }
+    }
+
+    fn into_val_slice_mut(mut self) -> &'a mut [V] {
+        unsafe {
+            slice::from_raw_parts_mut(
+                &mut self.as_leaf_mut().vals as *mut [V] as *mut V,
+                self.len()
             )
         }
     }
+
+    fn into_slices_mut(self) -> (&'a mut [K], &'a mut [V]) {
+        let k = unsafe { ptr::read(&self) };
+        (k.into_key_slice_mut(), self.into_val_slice_mut())
+    }
 }
 
 impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {