This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
warp_cache - a thread-safe Python caching decorator backed by a Rust extension (PyO3 + maturin). Uses SIEVE eviction, with TTL support, async awareness, and a cross-process shared memory backend.
make setup # Create venv + install dev deps (uv sync --dev)
make build # Build Rust extension (release, via maturin)
make build-debug # Build Rust extension (debug, faster compile)
make test # Build + run all tests
make test-only # Run tests without rebuilding
make fmt # Format Python (ruff) + Rust (cargo fmt)
make lint # Lint Python (ruff) + Rust (cargo clippy)
make all # Format, lint, testRun a single test:
uv run pytest tests/test_basic.py::test_cache_hit -vTest across Python versions:
make test-matrix -j # Parallel across 3.9-3.14
make test PYTHON=3.13 # Specific versionlib.rs- PyO3 module entry, exportsCachedFunction,SharedCachedFunction, info typesstore.rs- In-process backend:CachedFunctionuses shardedhashbrown::HashMapwith passthrough hasher (avoids re-hashing Python's precomputed hash) + GIL-conditional locking (GilCellunder GIL for zero-cost,parking_lot::RwLockunder free-threaded Python). The__call__hot path usesBorrowedArgsto look up via borrowed pointer (noCacheKeyallocation on hits), withCacheKeyonly materialized on cache miss for storageserde.rs- Fast-path binary serialization for common primitives (None, bool, int, float, str, bytes, flat tuples); avoids pickle overhead for the shared backendshared_store.rs- Cross-process backend:SharedCachedFunctionholdsShmCachedirectly (no Mutex), with cachedmax_key_size/max_value_sizefields and a pre-builtahash::RandomState. Serializes via serde.rs (with pickle fallback), stores in mmap'd shared memoryentry.rs-SieveEntry{ value, created_at, visited }key.rs-CacheKeywrapsPy<PyAny>+ precomputed hash; uses rawffi::PyObject_RichCompareBoolfor equality. Also providesBorrowedArgs(zero-alloc borrowed key for hit-path lookups via hashbrown'sEquivalenttrait)shm/- Shared memory infrastructure:mod.rs-ShmCache: create/open, get/set with serialized bytes. Uses interior mutability (&selfmethods): reads are lock-free (seqlock), writes acquire seqlock internally.next_unique_idisAtomicU64layout.rs- Header + SlotHeader structs, memory offsetsregion.rs-ShmRegion: mmap file management ($TMPDIR/warp_cache/{name}.data+{name}.lock)lock.rs-ShmSeqLock: seqlock (optimistic reads + TTAS spinlock) in shared memoryhashtable.rs- Open-addressing with linear probing (power-of-2 capacity, bitmask)ordering.rs- SIEVE eviction: intrusive linked list +sieve_evict()hand scan
_decorator.py-cache()factory: dispatches toCachedFunction(memory) orSharedCachedFunction(shared). Auto-detects async functions and wraps withAsyncCachedFunction(cache hit in Rust, only missesawaitthe coroutine)_strategies.py-Backend(IntEnum): MEMORY=0, SHARED=1
- Single FFI crossing: entire cache lookup happens in Rust
__call__, no Python wrapper overhead - Release profile: fat LTO +
codegen-units=1for cross-crate inlining of PyO3 wrappers - SIEVE eviction: unified across both backends. On hit, sets
visited=1(single-word store). On evict, hand scans for unvisited entry. Lock-free reads on both backends - Thread safety: GIL-conditional locking -
GilCell(zero-costUnsafeCellwrapper) under GIL-enabled Python,parking_lot::RwLockunder free-threaded Python (#[cfg(Py_GIL_DISABLED)]). Shared backend uses seqlock (optimistic reads + TTAS spinlock) - no Mutex. Under free-threaded Python, per-shardRwLockenables true parallel reads across cores - Borrowed key lookup: hit path uses
BorrowedArgs(raw pointer + precomputed hash) via hashbrown'sEquivalenttrait - noCacheKeyallocation, no refcount churn on hits - Passthrough hasher:
PassthroughHasherfeeds Python's precomputed hash directly to hashbrown, avoiding foldhash re-hashing (~1-2ns saved per lookup). Shard count is power-of-2 for bitmask indexing
- Hash table capacity must be power-of-2 - bitmask probing uses
hash & (capacity - 1). Always use.next_power_of_two() #[repr(C)]struct field ordering - place u64 fields before u32 to avoid implicit alignment padding; affectssize_ofassertions in layout.rs
- Python: ruff (rules: E, F, W, I, UP, B, SIM; line-length=100; target py39)
- Rust:
cargo clippy -- -D warnings