AptLarder::Cache
Filesystem-backed cache for APT packages and index files.
Each entry is stored as a plain file under root using the cache key as a
relative path. A .sha256 sidecar is written alongside every file so that
immutable entries can be verified on first serve without trusting the
filesystem alone. A .validators sidecar keeps the upstream Last-Modified
and ETag of an entry, so revalidation replays what upstream sent instead
of a local timestamp.
Three in-memory indices avoid redundant syscalls at runtime:
@known— keys confirmed present on disk (never shrinks while running)@mtime_cache— last-modified times, updated bystoreandtouch@verified— keys whose SHA256 has already been checked this session
All public methods are safe to call from concurrent fibers.
Constants
Every file kept alongside a data file. Scans skip them, and removing an entry removes all of them.
Constructors
Class methods
Returns true for a path or key ending with a sidecar suffix. Sidecars
belong to a data file and are never entries of their own; they share the
key namespace, so the proxy must never read or write such a key.
Case-insensitive: on APFS or a Docker Desktop bind mount Release.SHA256
is the very file Release.sha256.
Instance methods
Removes every cached entry (data files and their sidecars) in a single directory scan and clears all in-memory state. Returns the number of data files deleted.
Unlike iterating entries + invalidate, this builds no per-entry structs
and holds the whole listing only as a glob stream, so it stays cheap on
very large caches. Best-effort under concurrency: entries added while the
scan runs may survive (acceptable for an admin flush).
Returns paginated cache entries, optionally filtered by prefix. Scans the root directory on each call — intended for infrequent admin use.
Returns the number of cached data files.
Fast (no disk scan): maintained incrementally by store/invalidate/
clear, seeded from disk at construction, and re-anchored to the exact
on-disk count on every evict pass. May drift slightly between eviction
passes if files are added or removed out-of-band.
Deletes every cached file whose mtime is older than max_age.
Skips .sha256 and .validators sidecar files (they are removed
together with their parent by invalidate). Returns {files_deleted, bytes_freed}.
Performs time-based and/or size-based eviction in a single disk scan.
- max_age — delete files whose mtime is older than this span (
nil= skip) - limit_bytes — delete LRU files until total size is below this limit (
nil= skip)
Returns {files_deleted, bytes_freed}.
Convenience wrapper: time-based eviction only.
Convenience wrapper: size-based LRU eviction only.
Returns true if a file for key exists on disk.
Checks the in-memory @known set first to avoid a stat syscall on
repeated lookups. Adds the key to @known on the first disk hit.
Returns true if the cached file for key is younger than ttl.
Uses the in-memory mtime index when available, falling back to a single
stat call on first access. Returns false if the key is not cached.
Removes the file and its sidecars from disk and clears all in-memory state for key. Safe to call when the file does not exist.
Returns the modification time of the cached file, or nil if the file
does not exist or disappears between the call and the stat (TOCTOU safe).
Opens the cached file for key in read-only mode.
Raises File::Error if the key is not present.
Returns the byte size of the cached file for key.
Raises File::Error if the key is not present.
Streams io into the cache under key.
Writes to a randomly-named .tmp file first, then renames it into place
atomically. The SHA256 of the content is computed during the write at no
extra I/O cost and stored in a .sha256 sidecar file.
last_modified and etag are the upstream response validators; they are
kept in a .validators sidecar, which is removed when neither is given so
a re-stored entry never keeps the validators of its previous content.
If the write fails for any reason (network drop, disk full, …) the .tmp
file is deleted and the exception is re-raised. The destination is never
left in a partially-written state.
Updates the mtime of key to the current time and refreshes the in-memory index. Used to extend the freshness window after a 304 Not Modified response. Silently ignores missing files.
Returns true if the cached file matches its stored SHA256 sidecar.
Files that have no sidecar (written before integrity tracking was added)
are trusted unconditionally. Each file is hashed at most once per server
run: after the first successful check the key is added to @verified and
subsequent calls return immediately.
Returns the upstream validators stored for key, or nil when the entry
has none (missing entry, upstream sent neither header, or entry cached
before validators were recorded).