Standard Collections
BTreeMap<K, V>
BTreeMap<K, V> (std::collections::BTreeMap) is an ordered key-value associative map backed by a cache-friendly B-Tree that keeps keys sorted by K: Ord at all times and supports $O(\log n)$ lookup, insertion, removal, min/max queries, and key-range iteration.
Why Rust Uses a B-Tree Instead of a Binary Search Tree
Traditional balanced binary search trees (such as Red-Black or AVL trees, like C++'s std::map) allocate a separate heap node for every single (K, V) pair with parent/left/right pointers—incurring high memory overhead and a CPU cache miss on every tree level.
Rust's BTreeMap groups multiple keys and values (B = 6, storing up to 2B - 1 = 11 key-value pairs per node) in contiguous arrays inside each heap node:
Single B-Tree Node (up to 11 keys and 11 values in contiguous arrays):
+-----------------------------------------------+
| keys: [ 10 | 25 | 40 | 60 | 85 | .. ] | <-- scanned in 1-2 CPU cache lines
| vals: [ v0 | v1 | v2 | v3 | v4 | .. ] |
| edges: [ e0 | e1 | e2 | e3 | e4 | e5 | .. ] |
+-----------------------------------------------+
Core BTreeMap<K, V> Operations
| Operation | Method | Time Complexity |
|---|---|---|
| Insert / lookup / remove | map.insert(k, v) / map.get(&q) / map.remove(&q) |
$O(\log n)$ |
| Smallest key-value pair | map.first_key_value() / map.pop_first() |
$O(\log n)$ |
| Largest key-value pair | map.last_key_value() / map.pop_last() |
$O(\log n)$ |
| Ordered range iteration | map.range(start..=end) / map.range_mut(start..=end) |
$O(\log n + k)$ for $k$ yielded items |
use std::collections::BTreeMap;
fn main() {
let mut timeline = BTreeMap::from([
(1050_u64, "deploy_finished"),
(1000, "build_started"),
(1020, "tests_passed"),
(1010, "lint_ok"),
]);
println!("First event: {:?}", timeline.first_key_value());
println!("Last event: {:?}", timeline.last_key_value());
// Efficient range query over timestamps in `1005..=1030`:
println!("Events in 1005..=1030:");
for (ts, event) in timeline.range(1005..=1030) {
println!(" [{ts}] {event}");
}
let popped_earliest = timeline.pop_first();
println!("Popped earliest: {popped_earliest:?}");
}
First event: Some((1000, "build_started"))
Last event: Some((1050, "deploy_finished"))
Events in 1005..=1030:
[1010] lint_ok
[1020] tests_passed
Popped earliest: Some((1000, "build_started"))