diff options
| author | C Jones <code@calebjones.net> | 2018-05-01 15:26:49 -0400 |
|---|---|---|
| committer | C Jones <code@calebjones.net> | 2018-05-07 22:14:34 -0400 |
| commit | 5b94e9f053c3fecb0e29c89e453ecaf07d97218c (patch) | |
| tree | 7436f0906cfcd11722cc843fee28606463f44aca | |
| parent | fa62eba92ad9a3d25b200835a5cd3ca48b700d75 (diff) | |
| download | rust-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.rs | 66 |
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> { |
