Skip to content

Commit 8c4641b

Browse files
committed
BTreeMap: check some invariants, avoid recursion in depth first search
1 parent f7aac25 commit 8c4641b

File tree

3 files changed

+302
-41
lines changed

3 files changed

+302
-41
lines changed

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

+3-32
Original file line numberDiff line numberDiff line change
@@ -1236,10 +1236,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
12361236
right_root.fix_left_border();
12371237

12381238
if left_root.height() < right_root.height() {
1239-
self.recalc_length();
1239+
self.length = left_root.node_as_ref().calc_length();
12401240
right.length = total_num - self.len();
12411241
} else {
1242-
right.recalc_length();
1242+
right.length = right_root.node_as_ref().calc_length();
12431243
self.length = total_num - right.len();
12441244
}
12451245

@@ -1283,42 +1283,13 @@ impl<K: Ord, V> BTreeMap<K, V> {
12831283
{
12841284
DrainFilter { pred, inner: self.drain_filter_inner() }
12851285
}
1286+
12861287
pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
12871288
let root_node = self.root.as_mut().map(|r| r.node_as_mut());
12881289
let front = root_node.map(|rn| rn.first_leaf_edge());
12891290
DrainFilterInner { length: &mut self.length, cur_leaf_edge: front }
12901291
}
12911292

1292-
/// Calculates the number of elements if it is incorrect.
1293-
fn recalc_length(&mut self) {
1294-
fn dfs<'a, K, V>(node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>) -> usize
1295-
where
1296-
K: 'a,
1297-
V: 'a,
1298-
{
1299-
let mut res = node.len();
1300-
1301-
if let Internal(node) = node.force() {
1302-
let mut edge = node.first_edge();
1303-
loop {
1304-
res += dfs(edge.reborrow().descend());
1305-
match edge.right_kv() {
1306-
Ok(right_kv) => {
1307-
edge = right_kv.right_edge();
1308-
}
1309-
Err(_) => {
1310-
break;
1311-
}
1312-
}
1313-
}
1314-
}
1315-
1316-
res
1317-
}
1318-
1319-
self.length = dfs(self.root.as_ref().unwrap().node_as_ref());
1320-
}
1321-
13221293
/// Creates a consuming iterator visiting all the keys, in sorted order.
13231294
/// The map cannot be used after calling this.
13241295
/// The iterator element type is `K`.

0 commit comments

Comments
 (0)