Skip to main content

CacheStore

Struct CacheStore 

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

Cached module information stored on disk.

Entries are keyed on the ROOT-RELATIVE, forward-slash-normalised path, and the root is recorded once in the header. Absolute keys made the blob unusable anywhere but the directory that wrote it: a container job, a matrix over roots, a GitLab shell executor, or a plain cp -Rp to a sibling path paid the full decode of a multi-megabyte file and then missed every single lookup, with nothing on stderr to say so.

Implementations§

Source§

impl CacheStore

Source

pub fn new(root: &Path) -> CacheStore

Create a new empty cache anchored at root.

Source

pub fn load( cache_dir: &Path, root: &Path, expected_config_hash: u64, max_size_bytes: usize, ) -> Result<CacheStore, CacheRejection>

Load cache from disk.

§Errors

Returns the CacheRejection that decided against reuse. Every branch names itself instead of collapsing into a bare miss: a run that read a multi-megabyte blob and then refused it costs the same as a cold run but used to be indistinguishable from having no cache at all, and the config-hash branch in particular said nothing whatsoever. Callers carry the reason into the perf table and fallow doctor.

The version is read from the file header BEFORE the payload is decoded, because the two are decided by different things. A format bump changes the encoded shape, so decoding a blob from the previous release fails outright and never reaches a version comparison made afterwards: the most ordinary event there is (upgrading fallow) then reported “cache file could not be decoded”, which reads as corruption and sent people looking for a damaged disk. With the version in front, an upgrade says the format changed. The framing is checked separately from the version it carries, so an unframed or unreadable payload reports Undecodable rather than borrowing the upgrade message.

Every branch that refuses a file that DID exist logs at warn, because the user paid the read and got nothing back. Only the missing-file case stays quiet.

Source

pub fn load_counting_bytes( cache_dir: &Path, root: &Path, expected_config_hash: u64, max_size_bytes: usize, ) -> (Result<CacheStore, CacheRejection>, u64)

Self::load, plus the number of cache bytes read from disk.

The count is returned also when the cache is refused, because the run paid for the read either way. It is zero when no file was read.

Source

pub fn save( &mut self, cache_dir: &Path, config_hash: u64, max_size_bytes: usize, ) -> Result<(), String>

Save cache to disk with write-time size enforcement and atomic rename.

Source

pub fn get(&self, path: &Path, content_hash: u64) -> Option<&CachedModule>

Look up a cached module by path and content hash. Returns None if not cached or hash mismatch.

Source

pub fn insert(&mut self, path: &Path, module: CachedModule)

Insert or update a cached module.

Source

pub fn get_by_path_only(&self, path: &Path) -> Option<&CachedModule>

Look up a cached module by path only (ignoring hash).

Source

pub fn retain_paths(&mut self, files: &[DiscoveredFile]) -> bool

Remove cache entries for files that no longer exist on disk.

Returns true when any entry was removed.

The predicate is deliberately “still exists”, not “was discovered by this run”. Discovery is scoped: --production drops test and story files, --root narrows to a subtree, and ignorePatterns differs per command. Evicting whatever the current scope did not walk meant one --production run threw away the entries for every test file, and the next full run reparsed them from cold. Entries are keyed by absolute path, so the check is one symlink_metadata per undiscovered entry (symlink_metadata, not metadata, so a broken symlink still counts as present rather than being evicted as missing). Size is not this method’s concern: evict_lru_to_target remains the only guard on how large the blob may grow.

Source

pub fn len(&self) -> usize

Number of cached entries.

Source

pub fn is_empty(&self) -> bool

Whether the cache is empty.

Trait Implementations§

Source§

impl Debug for CacheStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'__de> Decode<'__de> for CacheStore

Source§

impl Default for CacheStore

Source§

fn default() -> CacheStore

Returns the “default value” for a type. Read more
Source§

impl Encode for CacheStore

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> DecodeOwned for T
where T: for<'de> Decode<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<'a, T> FromIn<'a, T> for T

Source§

fn from_in(t: T, _: &'a Allocator) -> T

Converts to this type from the input type within the given allocator.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<'a, T, U> IntoIn<'a, U> for T
where U: FromIn<'a, T>,

Source§

fn into_in(self, allocator: &'a Allocator) -> U

Converts this type into the (usually inferred) input type within the given allocator.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more