Skip to main content

EntityCache

Struct EntityCache 

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

Entity cache that maintains full projected entities with LRU eviction.

The cache is populated as mutations flow through the projector, regardless of subscriber state. When a new subscriber connects, they receive snapshots of all cached entities for their requested view.

§Only whole entities

Source mutations carry only the fields that changed. A patch for a key a view holds merges into the whole entity. A patch for a key it does not hold is stored only if it is the whole entity: storing a few changed fields would serve them as though they were the entity, in snapshots and in every derived view.

A VM linked through crate::EntityResync marks the mutation that creates each entity (PatchOrigin::Creation), which is stored as-is. Any other patch from it for a key a view does not hold (PatchOrigin::Change) is refused with CacheWrite::Refused — whether the view evicted the key or never held it, as after a restore. The projector then asks the VM for the whole entity, which follows in the VM’s next batch and is stored with EntityCache::store_whole. That holds however many entities the VM keeps and however long ago the view evicted the key.

A source that marks nothing (PatchOrigin::Unknown) leaves a new key and an evicted one looking alike. Each view therefore remembers the keys it evicted (bounded, most recent first) and refuses patches for them; a key evicted so long ago that it has been forgotten is taken for new. A source delete also ends an eviction.

Implementations§

Source§

impl EntityCache

Source

pub fn new() -> Self

Create a new entity cache with default configuration

Source

pub fn with_config(config: EntityCacheConfig) -> Self

Create a new entity cache with custom configuration

Source

pub fn max_entities_per_view(&self) -> usize

Maximum number of entities cached per view.

Derived sorted view caches are bounded by the same value so they never hold more entities than their source view caches.

Source

pub async fn upsert(&self, view_id: &str, key: &str, patch: Value) -> CacheWrite

Write a patch from a source that does not mark creations (PatchOrigin::Unknown).

Source

pub async fn upsert_with_append( &self, view_id: &str, key: &str, patch: Value, append_paths: &[String], origin: PatchOrigin, ) -> CacheWrite

Merge patch into the cached entity, store it as a new entity, or refuse it as part of an entity the cache does not hold (see the type docs).

Source

pub async fn upsert_with_lifetime( &self, view_id: &str, key: &str, patch: Value, append_paths: &[String], origin: PatchOrigin, account_position: Option<AccountPosition>, ) -> CacheWrite

Apply a projected patch with optional authoritative account ordering. _seq is consulted for lifetime changes only when no account position exists; the two ordering domains are never compared.

Source

pub async fn upsert_with_ordering( &self, view_id: &str, key: &str, patch: Value, append_paths: &[String], origin: PatchOrigin, ordering: LifetimeOrdering<'_>, ) -> CacheWrite

Apply a projected patch with both ordering domains supplied explicitly. Projections may omit _seq, so the projector passes its source cursor separately here.

Source

pub async fn store_whole(&self, view_id: &str, key: &str, entity: Value) -> bool

Store entity as the whole entity for key, replacing anything held and clearing an eviction: the source vouched for it being complete (see arete_interpreter::Mutation::mark_whole_entity).

Source

pub async fn store_whole_for_lifetime( &self, view_id: &str, key: &str, entity: Value, requested_account_position: Option<AccountPosition>, ) -> bool

Store a requested whole entity only if the request was made for the account lifetime that is still current.

Source

pub async fn store_whole_for_ordering( &self, view_id: &str, key: &str, entity: Value, requested_account_position: Option<AccountPosition>, requested_source_seq: Option<&str>, ) -> bool

Source

pub async fn store_whole_for_ordering_in_domain( &self, view_id: &str, key: &str, entity: Value, requested_account_position: Option<AccountPosition>, requested_source_seq: Option<&str>, requested_source_domain: SlotIndexDomain, ) -> bool

Source

pub async fn account_position( &self, view_id: &str, key: &str, ) -> Option<AccountPosition>

Source

pub async fn accepts_mutation( &self, view_id: &str, key: &str, _entity: &Value, creation: bool, ) -> bool

Source

pub async fn accepts_lifetime_mutation( &self, view_id: &str, key: &str, creation: bool, account_position: Option<AccountPosition>, ) -> bool

Source

pub async fn accepts_ordered_lifetime_mutation( &self, view_id: &str, key: &str, creation: bool, account_position: Option<AccountPosition>, source_seq: Option<&str>, ) -> bool

Source

pub async fn accepts_ordered_lifetime_mutation_in_domain( &self, view_id: &str, key: &str, creation: bool, account_position: Option<AccountPosition>, source_seq: Option<&str>, source_domain: SlotIndexDomain, ) -> bool

Source

pub async fn delete( &self, view_id: &str, key: &str, account_position: Option<AccountPosition>, ) -> bool

Apply an ordered source deletion. A delayed deletion never removes a newer recreation. Only a newer, explicitly marked creation can restart a deleted row; sparse patches and resends cannot resurrect it.

Source

pub async fn delete_current(&self, view_id: &str, key: &str) -> bool

Delete the lifetime currently held by the cache when the producer has no cursor to attach. This is an explicit, trusted operation: callers with ordering evidence must use Self::delete_ordered instead.

Source

pub async fn delete_ordered( &self, view_id: &str, key: &str, account_position: Option<AccountPosition>, source_seq: Option<&str>, ) -> bool

Delete using the producer’s own _seq ordering only when no authoritative account position is present.

Source

pub async fn delete_ordered_in_domain( &self, view_id: &str, key: &str, account_position: Option<AccountPosition>, source_seq: Option<&str>, source_domain: SlotIndexDomain, ) -> bool

Source

pub async fn dump_lifetimes(&self) -> EntityLifetimes

Source

pub async fn hydrate_lifetimes(&self, lifetimes: EntityLifetimes)

Source

pub async fn hydrate_legacy_tombstones(&self, tombstones: EntityTombstones)

Restore the old _seq barriers as account positions. Those barriers were written only by authoritative account deletion/recreation paths; whether the row exists distinguishes a live recreation from deletion.

Source

pub async fn deletion_is_current(&self, view_id: &str, key: &str) -> bool

Whether the shared cache says a published delete still represents the latest lifetime. Subscription tasks use this without mutating the cache a second time after the projector has already applied the delete.

Source

pub fn merge_patch( &self, base: &mut Value, patch: Value, append_paths: &[String], )

Merge a source patch into base with this cache’s append and array rules, for callers that keep their own full copy of an entity.

Source

pub fn merge_patch_shared( &self, entity: &mut SharedEntity, patch: Value, append_paths: &[String], )

Self::merge_patch for a SharedEntity: copies its fields first if another holder shares them, so the merge never reaches that holder.

Source

pub async fn remember_evicted( &self, view_id: &str, keys: impl IntoIterator<Item = String>, )

Treat keys as evicted from view_id unless the view holds them, so patches for them from a source that does not mark creations are refused. Used after a restore, when the VM holds entities the restored cache does not; a VM that marks creations makes this moot, and the view drops the memory with its first patch.

Source

pub async fn get_all(&self, view_id: &str) -> Vec<(String, Value)>

Get all cached entities for a view.

Returns a vector of (key, entity) pairs for sending as snapshots to new subscribers. Each is a copy; Self::get_all_shared returns the cached entities themselves.

Source

pub async fn get_all_shared(&self, view_id: &str) -> Vec<(String, SharedEntity)>

Every entity cached for a view, most recently used first, sharing their fields with the cache rather than copying them.

Source

pub async fn get_after( &self, view_id: &str, cursor: &str, limit: Option<usize>, ) -> Vec<(String, Value)>

Get entities with _seq greater than the provided cursor.

Returns entities that have been updated after the given cursor, sorted by _seq in ascending order. Useful for resuming from a specific point in the stream.

Source

pub async fn get(&self, view_id: &str, key: &str) -> Option<Value>

Get a copy of a specific entity from the cache.

Source

pub async fn get_shared(&self, view_id: &str, key: &str) -> Option<SharedEntity>

A specific cached entity, sharing its fields with the cache rather than copying them.

Source

pub async fn remove(&self, view_id: &str, key: &str) -> Option<Value>

Remove one entity after a source-wide delete.

The delete ends the entity, so the key is also forgotten as evicted: a later patch for it creates a new entity.

Source

pub async fn len(&self, view_id: &str) -> usize

Get the number of cached entities for a view

Source

pub async fn is_empty(&self, view_id: &str) -> bool

Check if the cache for a view is empty

Source

pub fn snapshot_config(&self) -> SnapshotBatchConfig

Get the snapshot batch configuration

Source

pub async fn clear(&self, view_id: &str)

Clear all cached entities for a view

Source

pub async fn clear_all(&self)

Source

pub async fn dump(&self) -> Vec<(String, Vec<(String, Value)>)>

Dump every view’s entities for a state snapshot.

Entries are ordered most-recently-used first; Self::hydrate relies on that to reconstruct LRU eviction order. Each is a copy; Self::dump_shared returns the cached entities themselves.

Source

pub async fn dump_shared(&self) -> Vec<(String, Vec<(String, SharedEntity)>)>

Self::dump, sharing the entities’ fields with the cache rather than copying them. They serialize exactly as the copies would.

Source

pub async fn hydrate(&self, views: Vec<(String, Vec<(String, Value)>)>)

Restore entities dumped by Self::dump, preserving LRU order.

Entities are inserted as-is (no merge): a snapshot holds fully projected entities, not patches. A snapshot saves each view’s copy of an entity on its own, so views of one export ({export}/{mode}) whose copies have the same fields (all but _version) share them again, as they did when saved. Only copies of one export are compared.

Source

pub async fn stats(&self) -> CacheStats

Trait Implementations§

Source§

impl Clone for EntityCache

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for EntityCache

Source§

fn default() -> Self

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

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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