mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
BTree: clarify order sanity enforced by range searches
This commit is contained in:
parent
195ad4830e
commit
33d22f8400
@ -1018,6 +1018,9 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
///
|
///
|
||||||
/// Panics if range `start > end`.
|
/// Panics if range `start > end`.
|
||||||
/// Panics if range `start == end` and both bounds are `Excluded`.
|
/// Panics if range `start == end` and both bounds are `Excluded`.
|
||||||
|
/// May panic if the [`Ord`] implementation of type `T` is ill-defined,
|
||||||
|
/// either because it does not form a total order or because it does not
|
||||||
|
/// correspond to the [`Ord`] implementation of type `K`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1061,6 +1064,9 @@ impl<K, V> BTreeMap<K, V> {
|
|||||||
///
|
///
|
||||||
/// Panics if range `start > end`.
|
/// Panics if range `start > end`.
|
||||||
/// Panics if range `start == end` and both bounds are `Excluded`.
|
/// Panics if range `start == end` and both bounds are `Excluded`.
|
||||||
|
/// May panic if the [`Ord`] implementation of type `T` is ill-defined,
|
||||||
|
/// either because it does not form a total order or because it does not
|
||||||
|
/// correspond to the [`Ord`] implementation of type `K`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -29,11 +29,18 @@ impl<BorrowType, K, V> LeafRange<BorrowType, K, V> {
|
|||||||
|
|
||||||
impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
|
||||||
/// Finds the distinct leaf edges delimiting a specified range in a tree.
|
/// Finds the distinct leaf edges delimiting a specified range in a tree.
|
||||||
/// Returns either a pair of different handles into the same tree or a pair
|
///
|
||||||
/// of empty options.
|
/// If such distinct edges exist, returns them in ascending order, meaning
|
||||||
|
/// that a non-zero number of calls to `next_unchecked` on the `front` of
|
||||||
|
/// the result and/or calls to `next_back_unchecked` on the `back` of the
|
||||||
|
/// result will eventually reach the same edge.
|
||||||
|
///
|
||||||
|
/// If there are no such edges, i.e., if the tree contains no key within
|
||||||
|
/// the range, returns a pair of empty options.
|
||||||
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Unless `BorrowType` is `Immut`, do not use the duplicate handles to
|
/// Unless `BorrowType` is `Immut`, do not use the handles to visit the same
|
||||||
/// visit the same KV twice.
|
/// KV twice.
|
||||||
unsafe fn find_leaf_edges_spanning_range<Q: ?Sized, R>(
|
unsafe fn find_leaf_edges_spanning_range<Q: ?Sized, R>(
|
||||||
self,
|
self,
|
||||||
range: R,
|
range: R,
|
||||||
|
@ -68,13 +68,18 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
|
|||||||
/// of the range is different from the edge matching the upper bound, i.e.,
|
/// of the range is different from the edge matching the upper bound, i.e.,
|
||||||
/// the nearest node that has at least one key contained in the range.
|
/// the nearest node that has at least one key contained in the range.
|
||||||
///
|
///
|
||||||
/// If found, returns an `Ok` with that node, the pair of edge indices in it
|
/// If found, returns an `Ok` with that node, the strictly ascending pair of
|
||||||
/// delimiting the range, and the corresponding pair of bounds for
|
/// edge indices in the node delimiting the range, and the corresponding
|
||||||
/// continuing the search in the child nodes, in case the node is internal.
|
/// pair of bounds for continuing the search in the child nodes, in case
|
||||||
|
/// the node is internal.
|
||||||
///
|
///
|
||||||
/// If not found, returns an `Err` with the leaf edge matching the entire
|
/// If not found, returns an `Err` with the leaf edge matching the entire
|
||||||
/// range.
|
/// range.
|
||||||
///
|
///
|
||||||
|
/// As a diagnostic service, panics if the range specifies impossible bounds
|
||||||
|
/// or if it witnesses that the `Ord` implementation of `Q` violates total
|
||||||
|
/// order or is inconsistent with the `Ord` implementation of `K`.
|
||||||
|
///
|
||||||
/// The result is meaningful only if the tree is ordered by key.
|
/// The result is meaningful only if the tree is ordered by key.
|
||||||
pub fn search_tree_for_bifurcation<'r, Q: ?Sized, R>(
|
pub fn search_tree_for_bifurcation<'r, Q: ?Sized, R>(
|
||||||
mut self,
|
mut self,
|
||||||
@ -115,6 +120,10 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
|
|||||||
let (lower_edge_idx, lower_child_bound) = self.find_lower_bound_index(lower_bound);
|
let (lower_edge_idx, lower_child_bound) = self.find_lower_bound_index(lower_bound);
|
||||||
let (upper_edge_idx, upper_child_bound) = self.find_upper_bound_index(upper_bound);
|
let (upper_edge_idx, upper_child_bound) = self.find_upper_bound_index(upper_bound);
|
||||||
if lower_edge_idx > upper_edge_idx {
|
if lower_edge_idx > upper_edge_idx {
|
||||||
|
// Since we already checked the range bounds, this can only
|
||||||
|
// happen if `Q: Ord` does not implement a total order or does
|
||||||
|
// not correspond to the `K: Ord` implementation that is used
|
||||||
|
// while populating the tree.
|
||||||
panic!("Ord is ill-defined in BTreeMap range")
|
panic!("Ord is ill-defined in BTreeMap range")
|
||||||
}
|
}
|
||||||
if lower_edge_idx < upper_edge_idx {
|
if lower_edge_idx < upper_edge_idx {
|
||||||
|
Loading…
Reference in New Issue
Block a user