Skip to content

Commit bb3de55

Browse files
authored
Add an OOM-handling BTreeMap implementation (#12712)
* Add an OOM-handling `BTreeMap` implementation * review feedback * fix docs links
1 parent dfc36b6 commit bb3de55

7 files changed

Lines changed: 1037 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/core/src/slab.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,4 +508,14 @@ impl<T> Slab<T> {
508508
Entry::Free { .. } => None,
509509
})
510510
}
511+
512+
/// Clear all of the values from inside this slab.
513+
///
514+
/// Does not deallocate internal storage.
515+
#[inline]
516+
pub fn clear(&mut self) {
517+
self.len = 0;
518+
self.free = None;
519+
self.entries.clear();
520+
}
511521
}

crates/environ/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ postcard = { workspace = true }
2323
cpp_demangle = { version = "0.4.3", optional = true }
2424
cranelift-entity = { workspace = true, features = ['enable-serde'] }
2525
cranelift-bitset = { workspace = true, features = ['enable-serde'] }
26+
cranelift-bforest = { workspace = true }
2627
hashbrown = { workspace = true, features = ["default-hasher"] }
2728
wasmparser = { workspace = true, features = ['validate', 'serde', 'features'] }
2829
indexmap = { workspace = true, features = ["serde"] }
@@ -57,6 +58,10 @@ arbitrary = { workspace = true, features = ["derive"] }
5758
name = "factc"
5859
required-features = ['component-model', 'compile']
5960

61+
[[example]]
62+
name = "btrees"
63+
required-features = ["std"]
64+
6065
[features]
6166
anyhow = ["wasmtime-core/anyhow"]
6267
backtrace = ["std", "wasmtime-core/backtrace"]

crates/environ/examples/btrees.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::{collections::BTreeMap, str::FromStr};
2+
use wasmtime_environ::{
3+
collections,
4+
error::{Context as _, Result, bail, format_err},
5+
};
6+
7+
type Key = [u128; 2];
8+
type Value = [u8; 16];
9+
10+
trait Map {
11+
fn insert(&mut self, key: Key, value: Value) -> Result<()>;
12+
}
13+
14+
impl Map for BTreeMap<Key, Value> {
15+
fn insert(&mut self, key: Key, value: Value) -> Result<()> {
16+
BTreeMap::insert(self, key, value);
17+
Ok(())
18+
}
19+
}
20+
21+
impl Map for collections::BTreeMap<Key, Value> {
22+
fn insert(&mut self, key: Key, value: Value) -> Result<()> {
23+
collections::BTreeMap::insert(self, key, value)?;
24+
Ok(())
25+
}
26+
}
27+
28+
fn main() -> Result<()> {
29+
let kind = std::env::args()
30+
.nth(1)
31+
.ok_or_else(|| format_err!("must provide first argument: 'std' or 'bforest'"))?;
32+
33+
let mut map: Box<dyn Map> = match kind.as_str() {
34+
"std" => Box::new(BTreeMap::new()),
35+
"bforest" => Box::new(collections::BTreeMap::new()),
36+
_ => bail!("first argument must be either 'std' or 'bforest', got: '{kind}'"),
37+
};
38+
39+
let n = std::env::args().nth(2);
40+
let n = n.as_deref().unwrap_or("1000");
41+
let n = u128::from_str(n).context("failed to parse second argument as `u32` integer")?;
42+
43+
println!("Inserting {n} entries into `{kind}`-based `BTreeMap`...");
44+
45+
for i in 0..n {
46+
map.insert([i, i], [0; 16])?;
47+
}
48+
49+
Ok(())
50+
}

crates/environ/src/collections.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
//! Fallible, OOM-handling collections.
22
3+
pub mod btree_map;
34
mod entity_set;
45
mod hash_map;
56
mod hash_set;
67
mod index_map;
78
mod primary_map;
89
mod secondary_map;
910

11+
pub use btree_map::BTreeMap;
1012
pub use entity_set::EntitySet;
1113
pub use hash_map::HashMap;
1214
pub use hash_set::HashSet;

0 commit comments

Comments
 (0)