pub struct DiskCache { /* private fields */ }Expand description
On-disk cache of inflated entries, derived indexes and rendered results.
Implementations§
Source§impl DiskCache
impl DiskCache
Sourcepub fn default_dir() -> Option<PathBuf>
pub fn default_dir() -> Option<PathBuf>
The default cache directory: $XDG_CACHE_HOME/asc, else on Windows
%LOCALAPPDATA%\\asc\\cache, else ~/.cache/asc.
Sourcepub fn open(dir: impl Into<PathBuf>) -> DiskCache
pub fn open(dir: impl Into<PathBuf>) -> DiskCache
A cache in dir with the default policy: automatic capacity, every
tier, DEFAULT_MIN_DEX_BYTES. Hosts apply the user’s configuration
with the with_* methods.
Sourcepub fn with_tiers(self, tiers: &[Tier]) -> DiskCache
pub fn with_tiers(self, tiers: &[Tier]) -> DiskCache
Use only tiers: reads of the others miss and writes to them are
skipped. Entries already stored in them still count and are evicted.
Sourcepub fn uses(&self, tier: Tier) -> bool
pub fn uses(&self, tier: Tier) -> bool
Whether tier is read and written (DiskCache::with_tiers).
Sourcepub fn with_min_dex_bytes(self, bytes: u64) -> DiskCache
pub fn with_min_dex_bytes(self, bytes: u64) -> DiskCache
Write inflated entries of at least bytes to L1 (0: all of them).
Sourcepub fn min_dex_bytes(&self) -> u64
pub fn min_dex_bytes(&self) -> u64
Smallest inflated entry worth writing to L1 (DEFAULT_MIN_DEX_BYTES
unless configured otherwise). DiskCache::put itself
writes whatever it is given; hosts ask DiskCache::admits_dex first.
Sourcepub fn admits_dex(&self, len: u64) -> bool
pub fn admits_dex(&self, len: u64) -> bool
Whether an inflated entry of len bytes is worth an L1 file
(DiskCache::min_dex_bytes).
Sourcepub fn with_min_derived_cost(self, cost: Duration) -> DiskCache
pub fn with_min_derived_cost(self, cost: Duration) -> DiskCache
Write derived indexes that took at least cost to build to L2
(default DEFAULT_MIN_DERIVED_COST; zero: all of them).
Sourcepub fn admits_derived(&self, cost: Duration) -> bool
pub fn admits_derived(&self, cost: Duration) -> bool
Whether an index that took cost to build is worth an L2 file.
Like DiskCache::admits_dex, a policy for hosts to apply.
Sourcepub fn open_default() -> Option<DiskCache>
pub fn open_default() -> Option<DiskCache>
Open the default directory, if one can be determined.
Sourcepub fn with_capacity(self, cap_bytes: u64) -> DiskCache
pub fn with_capacity(self, cap_bytes: u64) -> DiskCache
A fixed capacity of cap_bytes.
Sourcepub fn with_capacity_mode(self, cap: DiskCapacity) -> DiskCache
pub fn with_capacity_mode(self, cap: DiskCapacity) -> DiskCache
Bound the cache by cap.
Sourcepub fn capacity_mode(&self) -> DiskCapacity
pub fn capacity_mode(&self) -> DiskCapacity
How the cache is bounded.
Sourcepub fn capacity_for(&self, used: u64) -> u64
pub fn capacity_for(&self, used: u64) -> u64
Bytes the cache may hold when it holds used: the fixed capacity, or
the automatic budget for the file system’s current free space.
Sourcepub fn budget(&self) -> DiskBudget
pub fn budget(&self) -> DiskBudget
Capacity, usage and free space right now (walks the cache directory).
Sourcepub fn get(
&self,
key: &ApkKey,
entry_name: &str,
expected_len: u64,
) -> Option<DexData>
pub fn get( &self, key: &ApkKey, entry_name: &str, expected_len: u64, ) -> Option<DexData>
Map a cached entry if present and of the expected size (0: any). A file from before the current boot is checked against its CRC-32 first; a damaged one is deleted.
§Panics
Never: the CRC is read from a trailer of fixed size.
Sourcepub fn put(
&self,
key: &ApkKey,
entry_name: &str,
bytes: &[u8],
) -> Result<(), CacheError>
pub fn put( &self, key: &ApkKey, entry_name: &str, bytes: &[u8], ) -> Result<(), CacheError>
Store an inflated entry (atomic rename; concurrent writers are
harmless). Does not evict: call DiskCache::evict after a batch of
puts.
§Errors
CacheError::NotACacheDir when the directory is not this cache’s,
CacheError::LowDiskSpace when the write would eat into the free
space reserve, CacheError::Io when writing fails.
Sourcepub fn get_derived(
&self,
key: &ApkKey,
name: &str,
kind: &str,
version: u32,
) -> Option<Derived>
pub fn get_derived( &self, key: &ApkKey, name: &str, kind: &str, version: u32, ) -> Option<Derived>
Map the L2 index name (e.g. a logical DEX name) of kind at the
producer’s format version, as DiskCache::put_derived stored it.
A file of another version, a damaged header or a truncated payload
is a miss.
§Panics
Never: the header fields are read from a slice of the full header size.
Sourcepub fn put_derived(
&self,
key: &ApkKey,
name: &str,
kind: &str,
version: u32,
build_cost: Duration,
payload: &[u8],
) -> Result<(), CacheError>
pub fn put_derived( &self, key: &ApkKey, name: &str, kind: &str, version: u32, build_cost: Duration, payload: &[u8], ) -> Result<(), CacheError>
Store an L2 index (see DiskCache::get_derived). build_cost is
what rebuilding it takes: eviction keeps the indexes that save the
most time per byte.
§Errors
As DiskCache::put.
Sourcepub fn get_rendered(&self, key: &ApkKey, query: &str) -> Option<Vec<u8>>
pub fn get_rendered(&self, key: &ApkKey, query: &str) -> Option<Vec<u8>>
The L3 result stored under query (the query, its options and the
producer’s version: build it with rendered_key).
Sourcepub fn get_rendered_view(&self, key: &ApkKey, query: &str) -> Option<Rendered>
pub fn get_rendered_view(&self, key: &ApkKey, query: &str) -> Option<Rendered>
DiskCache::get_rendered without copying the payload out of its
cache file. The immutable file is mapped only after its full key and
CRC have been validated.
Sourcepub fn put_rendered(
&self,
key: &ApkKey,
query: &str,
payload: &[u8],
) -> Result<(), CacheError>
pub fn put_rendered( &self, key: &ApkKey, query: &str, payload: &[u8], ) -> Result<(), CacheError>
Sourcepub fn note_source(
&self,
key: &ApkKey,
apk_path: &Path,
) -> Result<(), CacheError>
pub fn note_source( &self, key: &ApkKey, apk_path: &Path, ) -> Result<(), CacheError>
Record where the APK of key lives, so eviction can tell the entries
of an APK deleted or replaced since (evicted first) from live ones.
Cheap to repeat; hosts call it once per APK. A program’s archives are
recorded one by one, each under its own key.
§Errors
As DiskCache::put.
Sourcepub fn stats(&self) -> (usize, usize, u64)
pub fn stats(&self) -> (usize, usize, u64)
(APKs, files, bytes) currently stored, over every tier (an APK
with data in several tiers counts once).
Sourcepub fn tier_stats(&self) -> [TierStats; 3]
pub fn tier_stats(&self) -> [TierStats; 3]
Usage of each tier, in Tier::ALL order.
Sourcepub fn clear(&self) -> Result<u64, CacheError>
pub fn clear(&self) -> Result<u64, CacheError>
Delete every cached entry of every tier (and nothing else). Returns
the number of bytes freed. Refuses to run on a directory that is not
a cache directory (see CACHEDIR_TAG).
§Errors
CacheError::NotACacheDir for a foreign directory, and
CacheError::Io when a file or directory cannot be removed.
Sourcepub fn check_usable(&self) -> Result<(), CacheError>
pub fn check_usable(&self) -> Result<(), CacheError>
Ok when the directory may be used as this cache (see
CACHEDIR_TAG), CacheError::NotACacheDir otherwise. Hosts call
this up front: DiskCache::put refuses such a directory too, but its
errors are usually swallowed by a background writer.
§Errors
CacheError::NotACacheDir when the directory exists without the
marker.
Source§impl DiskCache
impl DiskCache
Sourcepub fn evict(&self)
pub fn evict(&self)
Evict until under capacity (DiskCache::capacity_for,
re-evaluated against the current free space). Does nothing in a
directory that is not a cache directory (see CACHEDIR_TAG).
L3 is first trimmed to its own budget (the smaller of
RENDERED_MAX and 1/RENDERED_BUDGET_DIVISOR of the total) and
L2 to 1/DERIVED_BUDGET_DIVISOR. Over the total, entries of APKs
that are gone (DiskCache::note_source) go first, then L1 (the
largest, least recently used APK directories first), then L3 (least
recently used first), then L2 (least rebuild time saved per byte
first, discounted by age).
Source§impl DiskCache
impl DiskCache
Sourcepub fn evict_lazily(&self)
pub fn evict_lazily(&self)
DiskCache::evict, skipped when another walk happened less than
5 s ago and this handle has written less than 1/16 of the budget
since its own last walk. For hosts that evict after every burst of
writes: a process per query would otherwise walk the whole cache
thousands of times over a batch.