Skip to content

Commit 5b94e9f

Browse files
committed
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.
1 parent fa62eba commit 5b94e9f

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

src/liballoc/btree/node.rs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
393393
}
394394

395395
pub fn keys(&self) -> &[K] {
396-
self.reborrow().into_slices().0
396+
self.reborrow().into_key_slice()
397397
}
398398

399-
pub fn vals(&self) -> &[V] {
400-
self.reborrow().into_slices().1
399+
fn vals(&self) -> &[V] {
400+
self.reborrow().into_val_slice()
401401
}
402402

403403
/// 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> {
540540
}
541541

542542
pub fn keys_mut(&mut self) -> &mut [K] {
543-
unsafe { self.reborrow_mut().into_slices_mut().0 }
543+
unsafe { self.reborrow_mut().into_key_slice_mut() }
544544
}
545545

546546
pub fn vals_mut(&mut self) -> &mut [V] {
547-
unsafe { self.reborrow_mut().into_slices_mut().1 }
547+
unsafe { self.reborrow_mut().into_val_slice_mut() }
548548
}
549549
}
550550

551551
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
552-
pub fn into_slices(self) -> (&'a [K], &'a [V]) {
552+
fn into_key_slice(self) -> &'a [K] {
553553
unsafe {
554-
(
555-
slice::from_raw_parts(
556-
self.as_leaf().keys.as_ptr(),
557-
self.len()
558-
),
559-
slice::from_raw_parts(
560-
self.as_leaf().vals.as_ptr(),
561-
self.len()
562-
)
554+
slice::from_raw_parts(
555+
self.as_leaf().keys.as_ptr(),
556+
self.len()
557+
)
558+
}
559+
}
560+
561+
fn into_val_slice(self) -> &'a [V] {
562+
unsafe {
563+
slice::from_raw_parts(
564+
self.as_leaf().vals.as_ptr(),
565+
self.len()
563566
)
564567
}
565568
}
569+
570+
fn into_slices(self) -> (&'a [K], &'a [V]) {
571+
let k = unsafe { ptr::read(&self) };
572+
(k.into_key_slice(), self.into_val_slice())
573+
}
566574
}
567575

568576
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> {
574582
}
575583
}
576584

577-
pub fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) {
585+
fn into_key_slice_mut(mut self) -> &'a mut [K] {
578586
unsafe {
579-
(
580-
slice::from_raw_parts_mut(
581-
&mut self.as_leaf_mut().keys as *mut [K] as *mut K,
582-
self.len()
583-
),
584-
slice::from_raw_parts_mut(
585-
&mut self.as_leaf_mut().vals as *mut [V] as *mut V,
586-
self.len()
587-
)
587+
slice::from_raw_parts_mut(
588+
&mut self.as_leaf_mut().keys as *mut [K] as *mut K,
589+
self.len()
590+
)
591+
}
592+
}
593+
594+
fn into_val_slice_mut(mut self) -> &'a mut [V] {
595+
unsafe {
596+
slice::from_raw_parts_mut(
597+
&mut self.as_leaf_mut().vals as *mut [V] as *mut V,
598+
self.len()
588599
)
589600
}
590601
}
602+
603+
fn into_slices_mut(self) -> (&'a mut [K], &'a mut [V]) {
604+
let k = unsafe { ptr::read(&self) };
605+
(k.into_key_slice_mut(), self.into_val_slice_mut())
606+
}
591607
}
592608

593609
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {

0 commit comments

Comments
 (0)