Skip to content

Commit 6767371

Browse files
committed
Initial interning implementation
1 parent 2529bb0 commit 6767371

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ wasm-bindgen-test-crate-b = { path = 'tests/crates/b', version = '0.1' }
4949
[workspace]
5050
members = [
5151
"benchmarks",
52+
"crates/cache",
5253
"crates/cli",
5354
"crates/js-sys",
5455
"crates/test",
@@ -88,5 +89,6 @@ exclude = ['crates/typescript']
8889
[patch.crates-io]
8990
wasm-bindgen = { path = '.' }
9091
wasm-bindgen-futures = { path = 'crates/futures' }
92+
wasm-bindgen-cache = { path = 'crates/cache' }
9193
js-sys = { path = 'crates/js-sys' }
9294
web-sys = { path = 'crates/web-sys' }

crates/cache/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
authors = ["The wasm-bindgen Developers"]
3+
description = "Utilities for caching JS objects to avoid expensive copying"
4+
documentation = "https://docs.rs/wasm-bindgen-cache"
5+
homepage = "https://rustwasm.github.io/wasm-bindgen/"
6+
license = "MIT/Apache-2.0"
7+
name = "wasm-bindgen-cache"
8+
repository = "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/cache"
9+
readme = "./README.md"
10+
version = "0.1.0"
11+
edition = "2018"
12+
13+
[features]
14+
disabled = []
15+
16+
[dependencies]
17+
js-sys = { path = "../js-sys", version = '0.3.24' }
18+
uluru = "0.3.0"
19+
20+
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
21+
wasm-bindgen-test = { path = '../test', version = '0.2.47' }

crates/cache/src/lib.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#![deny(missing_docs)]
2+
3+
//!
4+
5+
6+
///
7+
pub mod intern {
8+
use js_sys::JsString;
9+
use std::cell::{Cell, RefCell};
10+
use uluru::{LRUCache, Entry};
11+
12+
struct Pair {
13+
key: String,
14+
value: JsString,
15+
}
16+
17+
// TODO figure out a good default capacity
18+
type Entries = LRUCache::<[Entry<Pair>; 1_024]>;
19+
20+
struct Cache {
21+
enabled: Cell<bool>,
22+
max_str_len: Cell<usize>,
23+
entries: RefCell<Entries>,
24+
}
25+
26+
// TODO figure out a good max_str_len
27+
thread_local! {
28+
static CACHE: Cache = Cache {
29+
enabled: Cell::new(true),
30+
max_str_len: Cell::new(128),
31+
entries: RefCell::new(LRUCache::default()),
32+
};
33+
}
34+
35+
fn get_js_string(cache: &mut Entries, key: &str) -> JsString {
36+
if let Some(p) = cache.find(|p| p.key == key) {
37+
p.value.clone()
38+
39+
} else {
40+
let value = JsString::from(key);
41+
42+
cache.insert(Pair {
43+
key: key.to_owned(),
44+
value: value.clone(),
45+
});
46+
47+
value
48+
}
49+
}
50+
51+
fn cache_str(s: &str) -> JsString {
52+
CACHE.with(|cache| {
53+
let should_cache =
54+
cache.enabled.get() &&
55+
s.len() <= cache.max_str_len.get();
56+
57+
if should_cache {
58+
get_js_string(&mut cache.entries.borrow_mut(), s)
59+
60+
} else {
61+
JsString::from(s)
62+
}
63+
})
64+
}
65+
66+
///
67+
#[inline]
68+
pub fn str(s: &str) -> JsString {
69+
if cfg!(feature = "disabled") {
70+
JsString::from(s)
71+
72+
} else {
73+
cache_str(s)
74+
}
75+
}
76+
77+
///
78+
#[inline]
79+
pub fn set_max_str_len(len: usize) {
80+
if !cfg!(feature = "disabled") {
81+
CACHE.with(|cache| cache.max_str_len.set(len));
82+
}
83+
}
84+
85+
///
86+
#[inline]
87+
pub fn enable() {
88+
if !cfg!(feature = "disabled") {
89+
CACHE.with(|cache| cache.enabled.set(true));
90+
}
91+
}
92+
93+
///
94+
#[inline]
95+
pub fn disable() {
96+
if !cfg!(feature = "disabled") {
97+
CACHE.with(|cache| cache.enabled.set(false));
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)