Skip to content

Commit 7b00a9e

Browse files
committed
wasm: Cache objects via data hash (XXH3)
1 parent 311de88 commit 7b00a9e

File tree

7 files changed

+60
-14
lines changed

7 files changed

+60
-14
lines changed

Cargo.lock

+11-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ strip = "debuginfo"
1414
codegen-units = 1
1515

1616
[workspace.package]
17-
version = "3.0.0-beta.4"
17+
version = "3.0.0-beta.5"
1818
authors = ["Luke Street <[email protected]>"]
1919
edition = "2024"
2020
license = "MIT OR Apache-2.0"

objdiff-wasm/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ std = ["objdiff-core/std"]
2525
[dependencies]
2626
log = { version = "0.4", default-features = false }
2727
regex = { version = "1.11", default-features = false, features = ["unicode-case"] }
28+
xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] }
2829

2930
[dependencies.objdiff-core]
3031
path = "../objdiff-core"

objdiff-wasm/package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objdiff-wasm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "objdiff-wasm",
3-
"version": "3.0.0-beta.4",
3+
"version": "3.0.0-beta.5",
44
"description": "A local diffing tool for decompilation projects.",
55
"author": {
66
"name": "Luke Street",

objdiff-wasm/src/api.rs

+42-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use alloc::{
22
format,
3-
rc::Rc,
3+
rc::{Rc, Weak},
44
str::FromStr,
55
string::{String, ToString},
66
vec::Vec,
@@ -9,6 +9,7 @@ use core::cell::RefCell;
99

1010
use objdiff_core::{diff, obj};
1111
use regex::{Regex, RegexBuilder};
12+
use xxhash_rust::xxh3::xxh3_64;
1213

1314
use super::logging;
1415

@@ -41,8 +42,7 @@ impl Guest for Component {
4142
fn version() -> String { env!("CARGO_PKG_VERSION").to_string() }
4243
}
4344

44-
#[repr(transparent)]
45-
struct ResourceObject(Rc<obj::Object>);
45+
struct ResourceObject(Rc<obj::Object>, u64);
4646

4747
struct ResourceObjectDiff(Rc<obj::Object>, diff::ObjectDiff);
4848

@@ -421,13 +421,49 @@ impl GuestDiffConfig for ResourceDiffConfig {
421421
}
422422
}
423423

424+
struct CachedObject(Weak<obj::Object>, u64);
425+
426+
struct ObjectCache(RefCell<Vec<CachedObject>>);
427+
428+
impl ObjectCache {
429+
#[inline]
430+
const fn new() -> Self { Self(RefCell::new(Vec::new())) }
431+
}
432+
433+
impl core::ops::Deref for ObjectCache {
434+
type Target = RefCell<Vec<CachedObject>>;
435+
436+
fn deref(&self) -> &Self::Target { &self.0 }
437+
}
438+
439+
// Assume single-threaded environment
440+
unsafe impl Sync for ObjectCache {}
441+
442+
static OBJECT_CACHE: ObjectCache = ObjectCache::new();
443+
424444
impl GuestObject for ResourceObject {
425445
fn parse(data: Vec<u8>, diff_config: DiffConfigBorrow) -> Result<Object, String> {
446+
let hash = xxh3_64(&data);
447+
let mut cached = None;
448+
OBJECT_CACHE.borrow_mut().retain(|c| {
449+
if c.0.strong_count() == 0 {
450+
return false;
451+
}
452+
if c.1 == hash {
453+
cached = c.0.upgrade();
454+
}
455+
true
456+
});
457+
if let Some(obj) = cached {
458+
return Ok(Object::new(ResourceObject(obj, hash)));
459+
}
426460
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
427-
obj::read::parse(&data, &diff_config)
428-
.map(|o| Object::new(ResourceObject(Rc::new(o))))
429-
.map_err(|e| e.to_string())
461+
let obj = Rc::new(obj::read::parse(&data, &diff_config).map_err(|e| e.to_string())?);
462+
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash));
463+
Ok(Object::new(ResourceObject(obj, hash)))
430464
}
465+
466+
fn hash(&self) -> u64 { self.1 }
431467
}
432468

433469
impl GuestObjectDiff for ResourceObjectDiff {

objdiff-wasm/wit/objdiff.wit

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ interface diff {
2020
data: list<u8>,
2121
config: borrow<diff-config>,
2222
) -> result<object, string>;
23+
24+
hash: func() -> u64;
2325
}
2426

2527
resource object-diff {

0 commit comments

Comments
 (0)