Skip to content

Commit c28e483

Browse files
committed
BTree: clarify order sanity enforced by range searches
1 parent 4dc66fd commit c28e483

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

alloc/src/collections/btree/map.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,9 @@ impl<K, V> BTreeMap<K, V> {
10181018
///
10191019
/// Panics if range `start > end`.
10201020
/// Panics if range `start == end` and both bounds are `Excluded`.
1021+
/// May panic if the [`Ord`] implementation of type `T` is ill-defined,
1022+
/// either because it does not form a total order or because it does not
1023+
/// correspond to the [`Ord`] implementation of type `K`.
10211024
///
10221025
/// # Examples
10231026
///
@@ -1061,6 +1064,9 @@ impl<K, V> BTreeMap<K, V> {
10611064
///
10621065
/// Panics if range `start > end`.
10631066
/// Panics if range `start == end` and both bounds are `Excluded`.
1067+
/// May panic if the [`Ord`] implementation of type `T` is ill-defined,
1068+
/// either because it does not form a total order or because it does not
1069+
/// correspond to the [`Ord`] implementation of type `K`.
10641070
///
10651071
/// # Examples
10661072
///

alloc/src/collections/btree/navigate.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,18 @@ impl<BorrowType, K, V> LeafRange<BorrowType, K, V> {
2929

3030
impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
3131
/// Finds the distinct leaf edges delimiting a specified range in a tree.
32-
/// Returns either a pair of different handles into the same tree or a pair
33-
/// of empty options.
32+
///
33+
/// If such distinct edges exist, returns them in ascending order, meaning
34+
/// that a non-zero number of calls to `next_unchecked` on the `front` of
35+
/// the result and/or calls to `next_back_unchecked` on the `back` of the
36+
/// result will eventually reach the same edge.
37+
///
38+
/// If there are no such edges, i.e., if the tree contains no key within
39+
/// the range, returns a pair of empty options.
40+
///
3441
/// # Safety
35-
/// Unless `BorrowType` is `Immut`, do not use the duplicate handles to
36-
/// visit the same KV twice.
42+
/// Unless `BorrowType` is `Immut`, do not use the handles to visit the same
43+
/// KV twice.
3744
unsafe fn find_leaf_edges_spanning_range<Q: ?Sized, R>(
3845
self,
3946
range: R,

alloc/src/collections/btree/search.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,18 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
6868
/// of the range is different from the edge matching the upper bound, i.e.,
6969
/// the nearest node that has at least one key contained in the range.
7070
///
71-
/// If found, returns an `Ok` with that node, the pair of edge indices in it
72-
/// delimiting the range, and the corresponding pair of bounds for
73-
/// continuing the search in the child nodes, in case the node is internal.
71+
/// If found, returns an `Ok` with that node, the strictly ascending pair of
72+
/// edge indices in the node delimiting the range, and the corresponding
73+
/// pair of bounds for continuing the search in the child nodes, in case
74+
/// the node is internal.
7475
///
7576
/// If not found, returns an `Err` with the leaf edge matching the entire
7677
/// range.
7778
///
79+
/// As a diagnostic service, panics if the range specifies impossible bounds
80+
/// or if it witnesses that the `Ord` implementation of `Q` violates total
81+
/// order or is inconsistent with the `Ord` implementation of `K`.
82+
///
7883
/// The result is meaningful only if the tree is ordered by key.
7984
pub fn search_tree_for_bifurcation<'r, Q: ?Sized, R>(
8085
mut self,
@@ -115,6 +120,10 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
115120
let (lower_edge_idx, lower_child_bound) = self.find_lower_bound_index(lower_bound);
116121
let (upper_edge_idx, upper_child_bound) = self.find_upper_bound_index(upper_bound);
117122
if lower_edge_idx > upper_edge_idx {
123+
// Since we already checked the range bounds, this can only
124+
// happen if `Q: Ord` does not implement a total order or does
125+
// not correspond to the `K: Ord` implementation that is used
126+
// while populating the tree.
118127
panic!("Ord is ill-defined in BTreeMap range")
119128
}
120129
if lower_edge_idx < upper_edge_idx {

0 commit comments

Comments
 (0)