fleche.storage.base
Attributes
Exceptions
Common base class for all non-exit exceptions. |
|
Inappropriate argument value (of correct type). |
Classes
Describes the kind of operation being performed on storage. |
|
Minimal base that exposes the |
|
Abstract base providing key-management helpers for any keyed storage. |
|
Primitive backend interface for key-value storage. |
|
Abstract domain interface for value storage. |
|
Bridges |
|
Abstract domain interface for call storage. |
|
Bridges |
Functions
|
Return the unique Digest for key prefix, or raise KeyError / AmbiguousDigestError. |
Module Contents
- exception fleche.storage.base.SaveError[source]
Bases:
ExceptionCommon base class for all non-exit exceptions.
- exception fleche.storage.base.AmbiguousDigestError[source]
Bases:
ValueErrorInappropriate argument value (of correct type).
- class fleche.storage.base.Intent[source]
Bases:
enum.StrEnumDescribes the kind of operation being performed on storage.
Mixins may use this to choose between exclusive and shared locks.
- fleche.storage.base._resolve_prefix(key: str, candidates: list[fleche.digest.Digest]) fleche.digest.Digest[source]
Return the unique Digest for key prefix, or raise KeyError / AmbiguousDigestError.
candidates must contain at most two entries (the two lexicographically smallest keys that start with key); callers are responsible for fetching them efficiently (e.g. via a
LIKE … LIMIT 2query for SQL backends).
- class fleche.storage.base.OperationContext[source]
Bases:
abc.ABCMinimal base that exposes the
_operation_context()hook.Both
KeyManagement(storage layer) andBaseCache(cache layer) inherit from this class so that the same thread-safety mixins (SerializingMixin,PerKeyLockMixin) can attach to either layer without duplication.- _operation_context(key: fleche.digest.Digest | str, *, intent: Intent = Intent.WRITE)[source]
Context manager entered around every operation on
key.The base implementation is a no-op. Override in a mixin to inject any resource scoped to the operation — a threading lock, a SQLAlchemy session, an open file handle, a decompression stream, etc.
Receiving
keylets implementations choose between a single global resource (ignore the key) or per-key resources (e.g. a striped lock table or a key-specific file handle).intentdescribes the kind of operation being performed. Mixins may use it to choose between exclusive and shared locks. Currently the only defined value isIntent.WRITE(the default).Composing multiple mixins: use
super()to chain so that every mixin in the MRO gets to wrap the operation:@contextlib.contextmanager def _operation_context(self, key, *, intent=Intent.WRITE): with self._lock: # this mixin's resource with super()._operation_context(key, intent=intent): yield
- class fleche.storage.base.KeyManagement[source]
Bases:
OperationContextAbstract base providing key-management helpers for any keyed storage.
Subclasses must implement
list,_evict, and_contains. The concrete helpersevict,contains,expand, andshrinkare implemented here once and inherited by all storage classes.Every public operation enters
_operation_context()around the compound work it performs, so mixins can inject an operation-scoped resource (e.g. a threading lock, a SQLAlchemy session, a file handle) without overriding every method individually.- abstractmethod list() Iterable[fleche.digest.Digest][source]
- abstractmethod _evict(key: fleche.digest.Digest) None[source]
- abstractmethod _contains(key: fleche.digest.Digest) bool[source]
- evict(key: fleche.digest.Digest | str) None[source]
Removes the entry corresponding to the key from the storage.
- contains(key: fleche.digest.Digest | str) bool[source]
- expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]
Expands a short-hand digest to the full length one.
- shrink(key: fleche.digest.Digest | str, /) fleche.digest.Digest[source]
- shrink(key: fleche.digest.Digest | str, /, *keys: fleche.digest.Digest | str) tuple[Digest, ...]
Find the shortest substring(s) that unambiguously reference each key.
With a single key, returns one
Digest. With multiple keys, returns a tuple ofDigestin the same order as the inputs; the batched form fetcheslist()once instead of per-key, which matters on backends where listing is expensive (e.g. SQL, filesystem).
- _shrink_one(key: Digest | str, sorted_all: Sequence[str]) fleche.digest.Digest[source]
- _normalize_key(key: fleche.digest.Digest | str) fleche.digest.Digest[source]
Expand a short digest prefix to a full key, or wrap a full key as Digest.
- class fleche.storage.base.StorageBackend[source]
Bases:
KeyManagementPrimitive backend interface for key-value storage.
Backends implement the low-level
put/get/_evict/listoperations. Higher-level classes (ValueMixin,CallMixin) add domain-specific logic on top.- abstractmethod put(value: Any, key: fleche.digest.Digest) fleche.digest.Digest[source]
- abstractmethod get(key: fleche.digest.Digest) Any[source]
- _contains(key: fleche.digest.Digest) bool[source]
- class fleche.storage.base.ValueStorage[source]
Bases:
KeyManagementAbstract domain interface for value storage.
- abstractmethod save(value: Any, key: fleche.digest.Digest | None = None) fleche.digest.Digest[source]
- abstractmethod load(key: fleche.digest.Digest | str) Any[source]
- class fleche.storage.base.ValueMixin[source]
Bases:
ValueStorage,StorageBackendBridges
ValueStoragewithStorageBackendprimitives.Implements
saveandloadusingputandget. Concrete classes inherit from this and aStorageBackendimplementation to get a fully functional value storage.- save(value: Any, key: fleche.digest.Digest | None = None) fleche.digest.Digest[source]
- load(key: fleche.digest.Digest | str) Any[source]
- class fleche.storage.base.CallStorage[source]
Bases:
KeyManagementAbstract domain interface for call storage.
- abstractmethod save(call: fleche.call.DigestedCall) fleche.digest.Digest[source]
- abstractmethod load(key: fleche.digest.Digest | str) fleche.call.DigestedCall[source]
- abstractmethod query(template: fleche.call.QueryCall) Iterable[fleche.call.DigestedCall][source]
- transform(func: Callable[[fleche.call.DigestedCall], fleche.call.DigestedCall] | None = None) None[source]
Applies a transformation function to all DigestedCall objects in the storage.
- Parameters:
func – A function that takes a
DigestedCalland returns a transformed one. IfNone, the identity is used (useful for re-calculating keys).
- class fleche.storage.base.CallMixin[source]
Bases:
CallStorage,StorageBackendBridges
CallStoragewithStorageBackendprimitives.Implements
save,load, andqueryusingputandget, deriving the storage key from the call’s lookup key.transformis inherited fromCallStorage.Concrete classes inherit from this and a
StorageBackendimplementation to get a fully functional call storage.- load(key: fleche.digest.Digest | str) fleche.call.DigestedCall[source]
- query(template: fleche.call.QueryCall) Iterable[fleche.call.DigestedCall][source]
Find cached calls that ‘match’ the template.
Returns all calls where the given arguments, results or metadata match exactly the stored ones. Values may be given either as they are or as
Digest.- Parameters:
template (Call) – specification for calls to return; use None as wildcard.
- Returns:
an iterable over all matching digested call objects
- Return type:
Iterable[DigestedCall]