Skip to main content

DiskCache

Struct DiskCache 

Source
pub struct DiskCache { /* private fields */ }
Expand description

On-disk cache of inflated entries, derived indexes and rendered results.

Implementations§

Source§

impl DiskCache

Source

pub fn default_dir() -> Option<PathBuf>

The default cache directory: $XDG_CACHE_HOME/asc, else ~/.cache/asc.

Source

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.

Source

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.

Source

pub fn uses(&self, tier: Tier) -> bool

Source

pub fn with_min_dex_bytes(self, bytes: u64) -> DiskCache

Write inflated entries of at least bytes to L1 (0: all of them).

Source

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.

Source

pub fn admits_dex(&self, len: u64) -> bool

Source

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).

Source

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.

Source

pub fn open_default() -> Option<DiskCache>

Open the default directory, if one can be determined.

Source

pub fn with_capacity(self, cap_bytes: u64) -> DiskCache

A fixed capacity of cap_bytes.

Source

pub fn with_capacity_mode(self, cap: DiskCapacity) -> DiskCache

Source

pub fn capacity_mode(&self) -> DiskCapacity

Source

pub fn dir(&self) -> &Path

Source

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.

Source

pub fn budget(&self) -> DiskBudget

Capacity, usage and free space right now (walks the cache directory).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn put_rendered( &self, key: &ApkKey, query: &str, payload: &[u8], ) -> Result<(), CacheError>

Store an L3 result (see DiskCache::get_rendered).

Source

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.

Source

pub fn stats(&self) -> (usize, usize, u64)

(APKs, files, bytes) currently stored, over every tier (an APK with data in several tiers counts once).

Source

pub fn tier_stats(&self) -> [TierStats; 3]

Usage of each tier, in Tier::ALL order.

Source

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).

Source

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.

Source§

impl DiskCache

Source

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

Source

pub fn evict_lazily(&self)

DiskCache::evict, skipped when another walk happened less than [EVICT_INTERVAL] ago and this handle has written less than 1/[EVICT_WRITE_DIVISOR] 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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.