Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify into_key_slice_mut #67725

Merged
merged 2 commits into from
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions src/liballoc/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {

/// Borrows a view into the values stored in the node.
/// The caller must ensure that the node is not the shared root.
/// This function is not public, so doesn't have to support shared roots like `keys` does.
fn vals(&self) -> &[V] {
self.reborrow().into_val_slice()
}
Expand Down Expand Up @@ -514,6 +515,7 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
}

/// The caller must ensure that the node is not the shared root.
/// This function is not public, so doesn't have to support shared roots like `keys` does.
fn keys_mut(&mut self) -> &mut [K] {
unsafe { self.reborrow_mut().into_key_slice_mut() }
}
Expand Down Expand Up @@ -589,20 +591,15 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
unsafe { &mut *(self.root as *mut Root<K, V>) }
}

/// The caller must ensure that the node is not the shared root.
fn into_key_slice_mut(mut self) -> &'a mut [K] {
ssomers marked this conversation as resolved.
Show resolved Hide resolved
// Same as for `into_key_slice` above, we try to avoid a run-time check.
if (mem::align_of::<NodeHeader<K, V, K>>() > mem::align_of::<NodeHeader<K, V>>()
|| mem::size_of::<NodeHeader<K, V, K>>() != mem::size_of::<NodeHeader<K, V>>())
&& self.is_shared_root()
{
&mut []
} else {
unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys),
self.len(),
)
}
debug_assert!(!self.is_shared_root());
// We cannot be the shared root, so `as_leaf_mut` is okay.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We? I'd prefer something more objective like the slice or whatever it is

Copy link
Contributor Author

@ssomers ssomers Dec 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't actually write that comment, and think it's somewhat superfluous, but please come up with a concrete suggestion here, like:

  • // self cannot be the shared root
  • // This NodeRef cannot be the shared root
  • // Our node reference cannot be the shared root
  • // This node cannot be the shared root

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go with:

self cannot be the shared root

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's any better, on the contrary, it comes across as poor grammar and capitalization to me. Also, there are already at least 3 comments of this "we = self" style in the file, so at least one author and one reviewer didn't object.

Copy link
Contributor Author

@ssomers ssomers Jan 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The style of the public API documentation of Option, Vector, BTreeSet, leads to (in unscientifically determined order of popularity):

  • // The node cannot be the shared root
  • // The NodeRef cannot be the shared root

If there are multiple instances involved, we explicitly use self (with backticks). Somehow, its awkward capitalization is carefully avoided, except Vec::split_off

unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys),
self.len(),
)
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/liballoc/collections/btree/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ where
}
}

/// Returns the index in the node at which the key (or an equivalent) exists
/// or could exist, and whether it exists in the node itself. If it doesn't
/// exist in the node itself, it may exist in the subtree with that index
/// (if the node has subtrees). If the key doesn't exist in node or subtree,
/// the returned index is the position or subtree to insert at.
pub fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
node: &NodeRef<BorrowType, K, V, Type>,
key: &Q,
Expand All @@ -54,6 +59,12 @@ where
Q: Ord,
K: Borrow<Q>,
{
// This function is defined over all borrow types (immutable, mutable, owned),
// and may be called on the shared root in each case.
// Crucially, we use `keys()` here, i.e., we work with immutable data.
// `keys_mut()` does not support the shared root, so we cannot use it.
// Using `keys()` is fine here even if BorrowType is mutable, as all we return
// is an index -- not a reference.
for (i, k) in node.keys().iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Expand Down