Skip to content

Commit 2564135

Browse files
authored
Rollup merge of rust-lang#75519 - ssomers:btree_splitpoint_cleanup, r=Mark-Simulacrum
BTreeMap: refactor splitpoint and move testing over to unit test r? @Mark-Simulacrum
2 parents 00e2dcb + 421e0ff commit 2564135

File tree

3 files changed

+37
-31
lines changed

3 files changed

+37
-31
lines changed

library/alloc/src/collections/btree/node.rs

+11-31
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ use crate::boxed::Box;
4343
const B: usize = 6;
4444
pub const MIN_LEN: usize = B - 1;
4545
pub const CAPACITY: usize = 2 * B - 1;
46+
const KV_IDX_CENTER: usize = B - 1;
47+
const EDGE_IDX_LEFT_OF_CENTER: usize = B - 1;
48+
const EDGE_IDX_RIGHT_OF_CENTER: usize = B;
4649

4750
/// The underlying representation of leaf nodes.
4851
#[repr(C)]
@@ -834,38 +837,12 @@ enum InsertionPlace {
834837
fn splitpoint(edge_idx: usize) -> (usize, InsertionPlace) {
835838
debug_assert!(edge_idx <= CAPACITY);
836839
// Rust issue #74834 tries to explain these symmetric rules.
837-
let middle_kv_idx;
838-
let insertion;
839-
if edge_idx <= B - 2 {
840-
middle_kv_idx = B - 2;
841-
insertion = InsertionPlace::Left(edge_idx);
842-
} else if edge_idx == B - 1 {
843-
middle_kv_idx = B - 1;
844-
insertion = InsertionPlace::Left(edge_idx);
845-
} else if edge_idx == B {
846-
middle_kv_idx = B - 1;
847-
insertion = InsertionPlace::Right(0);
848-
} else {
849-
middle_kv_idx = B;
850-
let new_edge_idx = edge_idx - (B + 1);
851-
insertion = InsertionPlace::Right(new_edge_idx);
852-
}
853-
let mut left_len = middle_kv_idx;
854-
let mut right_len = CAPACITY - middle_kv_idx - 1;
855-
match insertion {
856-
InsertionPlace::Left(edge_idx) => {
857-
debug_assert!(edge_idx <= left_len);
858-
left_len += 1;
859-
}
860-
InsertionPlace::Right(edge_idx) => {
861-
debug_assert!(edge_idx <= right_len);
862-
right_len += 1;
863-
}
840+
match edge_idx {
841+
0..EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER - 1, InsertionPlace::Left(edge_idx)),
842+
EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Left(edge_idx)),
843+
EDGE_IDX_RIGHT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Right(0)),
844+
_ => (KV_IDX_CENTER + 1, InsertionPlace::Right(edge_idx - (KV_IDX_CENTER + 1 + 1))),
864845
}
865-
debug_assert!(left_len >= MIN_LEN);
866-
debug_assert!(right_len >= MIN_LEN);
867-
debug_assert!(left_len + right_len == CAPACITY);
868-
(middle_kv_idx, insertion)
869846
}
870847

871848
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
@@ -1600,3 +1577,6 @@ unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T {
16001577
ret
16011578
}
16021579
}
1580+
1581+
#[cfg(test)]
1582+
mod tests;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::*;
2+
3+
#[test]
4+
fn test_splitpoint() {
5+
for idx in 0..=CAPACITY {
6+
let (middle_kv_idx, insertion) = splitpoint(idx);
7+
8+
// Simulate performing the split:
9+
let mut left_len = middle_kv_idx;
10+
let mut right_len = CAPACITY - middle_kv_idx - 1;
11+
match insertion {
12+
InsertionPlace::Left(edge_idx) => {
13+
assert!(edge_idx <= left_len);
14+
left_len += 1;
15+
}
16+
InsertionPlace::Right(edge_idx) => {
17+
assert!(edge_idx <= right_len);
18+
right_len += 1;
19+
}
20+
}
21+
assert!(left_len >= MIN_LEN);
22+
assert!(right_len >= MIN_LEN);
23+
assert!(left_len + right_len == CAPACITY);
24+
}
25+
}

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#![feature(container_error_extra)]
9494
#![feature(dropck_eyepatch)]
9595
#![feature(exact_size_is_empty)]
96+
#![feature(exclusive_range_pattern)]
9697
#![feature(extend_one)]
9798
#![feature(fmt_internals)]
9899
#![feature(fn_traits)]

0 commit comments

Comments
 (0)