Expand description
rkyv-backed bytecode cache for zsh scripts.
Single-file shard at ~/.zshrs/scripts.rkyv. On 2+ runs of a given
script, lex/parse/compile is skipped — the cache hit is mmap + zero-copy
ArchivedHashMap lookup + bincode-decode of the inner fusevm::Chunk blob.
Storage layout (rkyv archived):
ScriptShard {
header: { magic, format_version, zshrs_version, pointer_width, built_at_secs },
entries: HashMap<canonical_path, ScriptEntry>,
}
ScriptEntry { mtime_secs, mtime_nsecs, binary_mtime_at_cache, cached_at_secs,
chunk_blob: Vec<u8> }
Inner chunk_blob is bincode for now — fusevm::Chunk is owned by the
upstream fusevm crate and only derives serde::Serialize/Deserialize,
not rkyv::Archive, so the inner codec stays bincode inside the rkyv outer
container. Direct rkyv on Chunk would require either forking fusevm or a
mirror archived type — both are large refactors and not needed for the
current “kill SQLite for bytecode” goal.
Read path:
- Lazy
mmapof the shard, kept alive for the process lifetime so repeat lookups pay validation once. rkyv::check_archived_root::<ScriptShard>validates the byte image.- Header validated for magic / format_version / zshrs_version / pointer_width.
- Per-entry: source mtime must match, and
binary_mtime_at_cache≥ running zshrs binary’s mtime (any rebuild of zshrs invalidates entries silently).
Write path:
bin_zsystem_flock(LOCK_EX)onscripts.rkyv.lockso concurrent writers serialize.- Read existing shard into owned form, mutate,
rkyv::to_bytes, write toscripts.rkyv.tmp.<pid>.<nanos>, fsync, atomic-rename. - Drop the in-process
mmapso the next read picks up the new shard.
Ported from strykelang/strykelang/script_cache.rs (the user’s stryke
language has the same caching pattern; this is the same shape with ZRSC
magic, zshrs version pin, and a single chunk_blob per entry — zshrs has
no separate AST cache).
Structs§
- Archived
Script Entry - An archived
ScriptEntry - Archived
Script Shard - An archived
ScriptShard - Archived
Shard Header - An archived
ShardHeader - Mmapped
Shard - mmap + validated
*const ArchivedScriptShard. Self-referential — the pointer is valid for the lifetime of the wrapping struct. - Script
Cache - Shard cache keyed by canonical script path. One per shard file.
- Script
Entry - Script
Entry Resolver - The resolver for an archived
ScriptEntry - Script
Shard - Script
Shard Resolver - The resolver for an archived
ScriptShard - Shard
Header - Shard
Header Resolver - The resolver for an archived
ShardHeader
Constants§
- SHARD_
FORMAT_ VERSION - Bumped on incompatible rkyv schema changes.
- SHARD_
MAGIC - Magic header bytes — fail-fast if a wrong-format file is mmap’d. “ZRSC” little-endian.
Statics§
- CACHE
- Process-wide
ScriptCacherooted atdefault_cache_path().Nonewhen the cache is disabled or the path could not be opened.
Functions§
- cache_
enabled ZSHRS_CACHE=0|false|nodisables the cache entirely.- clear
- default_
cache_ path - Default shard path:
~/.zshrs/scripts.rkyv. - evict_
stale - file_
mtime - stats
- try_
load_ bytes - Try to load cached chunk-bytes by source path. Returns
Noneon any miss. - try_
save_ bytes - Store bincode-encoded
fusevm::Chunkbytes for a script path. Best-effort — cache disabled / canonicalize failure / mtime stat failure all returnOk(())silently so the caller can fire-and-forget.