Skip to main content

HashMapStore

Struct HashMapStore 

Source
pub struct HashMapStore {
Show 36 fields pub roots: RwLock<HashMap<EntityId, Root>>, pub workspaces: RwLock<HashMap<EntityId, Workspace>>, pub systems: RwLock<HashMap<EntityId, System>>, pub entities: RwLock<HashMap<EntityId, Entity>>, pub fields: RwLock<HashMap<EntityId, Field>>, pub features: RwLock<HashMap<EntityId, Feature>>, pub files: RwLock<HashMap<EntityId, File>>, pub use_cases: RwLock<HashMap<EntityId, UseCase>>, pub dtos: RwLock<HashMap<EntityId, Dto>>, pub dto_fields: RwLock<HashMap<EntityId, DtoField>>, pub globals: RwLock<HashMap<EntityId, Global>>, pub relationships: RwLock<HashMap<EntityId, Relationship>>, pub user_interfaces: RwLock<HashMap<EntityId, UserInterface>>, pub jn_system_from_root_system: RwLock<HashMapJunction>, pub jn_workspace_from_root_workspace: RwLock<HashMapJunction>, pub jn_entity_from_workspace_entities: RwLock<HashMapJunction>, pub jn_feature_from_workspace_features: RwLock<HashMapJunction>, pub jn_global_from_workspace_global: RwLock<HashMapJunction>, pub jn_user_interface_from_workspace_user_interface: RwLock<HashMapJunction>, pub jn_file_from_system_files: RwLock<HashMapJunction>, pub jn_field_from_entity_fields: RwLock<HashMapJunction>, pub jn_entity_from_entity_inherits_from: RwLock<HashMapJunction>, pub jn_relationship_from_entity_relationships: RwLock<HashMapJunction>, pub jn_entity_from_field_entity: RwLock<HashMapJunction>, pub jn_use_case_from_feature_use_cases: RwLock<HashMapJunction>, pub jn_entity_from_file_entity: RwLock<HashMapJunction>, pub jn_feature_from_file_feature: RwLock<HashMapJunction>, pub jn_field_from_file_field: RwLock<HashMapJunction>, pub jn_use_case_from_file_use_case: RwLock<HashMapJunction>, pub jn_dto_from_use_case_dto_in: RwLock<HashMapJunction>, pub jn_dto_from_use_case_dto_out: RwLock<HashMapJunction>, pub jn_entity_from_use_case_entities: RwLock<HashMapJunction>, pub jn_dto_field_from_dto_fields: RwLock<HashMapJunction>, pub jn_entity_from_relationship_left_entity: RwLock<HashMapJunction>, pub jn_entity_from_relationship_right_entity: RwLock<HashMapJunction>, pub counters: RwLock<HashMap<String, EntityId>>, /* private fields */
}

Fields§

§roots: RwLock<HashMap<EntityId, Root>>§workspaces: RwLock<HashMap<EntityId, Workspace>>§systems: RwLock<HashMap<EntityId, System>>§entities: RwLock<HashMap<EntityId, Entity>>§fields: RwLock<HashMap<EntityId, Field>>§features: RwLock<HashMap<EntityId, Feature>>§files: RwLock<HashMap<EntityId, File>>§use_cases: RwLock<HashMap<EntityId, UseCase>>§dtos: RwLock<HashMap<EntityId, Dto>>§dto_fields: RwLock<HashMap<EntityId, DtoField>>§globals: RwLock<HashMap<EntityId, Global>>§relationships: RwLock<HashMap<EntityId, Relationship>>§user_interfaces: RwLock<HashMap<EntityId, UserInterface>>§jn_system_from_root_system: RwLock<HashMapJunction>§jn_workspace_from_root_workspace: RwLock<HashMapJunction>§jn_entity_from_workspace_entities: RwLock<HashMapJunction>§jn_feature_from_workspace_features: RwLock<HashMapJunction>§jn_global_from_workspace_global: RwLock<HashMapJunction>§jn_user_interface_from_workspace_user_interface: RwLock<HashMapJunction>§jn_file_from_system_files: RwLock<HashMapJunction>§jn_field_from_entity_fields: RwLock<HashMapJunction>§jn_entity_from_entity_inherits_from: RwLock<HashMapJunction>§jn_relationship_from_entity_relationships: RwLock<HashMapJunction>§jn_entity_from_field_entity: RwLock<HashMapJunction>§jn_use_case_from_feature_use_cases: RwLock<HashMapJunction>§jn_entity_from_file_entity: RwLock<HashMapJunction>§jn_feature_from_file_feature: RwLock<HashMapJunction>§jn_field_from_file_field: RwLock<HashMapJunction>§jn_use_case_from_file_use_case: RwLock<HashMapJunction>§jn_dto_from_use_case_dto_in: RwLock<HashMapJunction>§jn_dto_from_use_case_dto_out: RwLock<HashMapJunction>§jn_entity_from_use_case_entities: RwLock<HashMapJunction>§jn_dto_field_from_dto_fields: RwLock<HashMapJunction>§jn_entity_from_relationship_left_entity: RwLock<HashMapJunction>§jn_entity_from_relationship_right_entity: RwLock<HashMapJunction>§counters: RwLock<HashMap<String, EntityId>>

Implementations§

Source§

impl HashMapStore

Source

pub fn new() -> Self

Source

pub fn snapshot(&self) -> HashMapStoreSnapshot

Clone the entire store for savepoint support. O(1) thanks to im::HashMap. (Poison-tolerant, but NOT atomic across tables — used for savepoints, which are taken on the single writer thread with no concurrent writer; use Self::freeze when an atomic cross-table snapshot is required.)

Source

pub fn freeze(&self) -> HashMapStore

Atomically snapshot the whole store into a fresh, isolated HashMapStore.

Unlike Self::snapshot, this holds a read guard on every table, junction, and the counters simultaneously while cloning, so the result is a single consistent point-in-time view of the store at the instant freeze runs. O(1) clones (im::HashMap structural sharing); the lock hold is just the clones. The returned store carries no savepoints and is meant to back a read-only (frozen) transaction.

Deadlock-freedom depends on an invariant (unenforced by the type system): guards are acquired in the struct’s declared field order (all entity tables, then all junctions, then counters), and no writer ever holds two entity-table locks simultaneously — each writer takes at most one entity table, then its junctions, in table-before-junction order (see remove_multi). A future cascade that nested two entity-table locks would violate this and could deadlock against freeze; keep cascades single-table.

SCOPE: freeze is atomic w.r.t. itself, not w.r.t. a writer’s multi-step cascade. A write transaction is not one critical section — its per-repo calls each lock/unlock independently — so a cascading delete/create can leave a brief window (e.g. child rows removed but the parent’s junction not yet cleared) into which freeze can land and capture a cross-table-torn snapshot (gather then hits “entity vanished mid-read”, or silently omits a just-added-but-unlinked row). This shrinks the torn-read window from the whole read to a single instant, but does not eliminate it; a store-wide writer/reader gate would be required to fully close it.

Source

pub fn restore(&self, snap: &HashMapStoreSnapshot)

Restore from a savepoint snapshot.

Source

pub fn create_savepoint(&self) -> u64

Create a savepoint by snapshotting the entire store. Returns a savepoint id. O(1) thanks to im::HashMap structural sharing.

Source

pub fn restore_savepoint(&self, savepoint_id: u64)

Restore the store to a previously created savepoint.

Source

pub fn discard_savepoint(&self, savepoint_id: u64)

Discard a savepoint without restoring (used on successful commit, and after a rollback so a rolled-back transaction doesn’t leak its snapshot).

Source

pub fn restore_without_counters(&self, snap: &HashMapStoreSnapshot)

Restore entity and junction data but preserve current counters. Used for undo snapshots where IDs must remain monotonically increasing.

Source

pub fn store_snapshot(&self) -> StoreSnapshot

Create a type-erased store snapshot for undo.

Source

pub fn restore_store_snapshot(&self, snap: &StoreSnapshot)

Restore from a type-erased store snapshot (preserves counters).

Source

pub fn check_junction_indexes(&self) -> Result<(), String>

Check every junction’s reverse index against a rebuild from its rows, and that each junction is exclusive exactly when its relationship is.

A diagnostic for tests: it walks every junction, so it costs O(store). Nothing calls it on a write path. Returns the first discrepancy found.

Trait Implementations§

Source§

impl Debug for HashMapStore

Source§

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

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

impl Default for HashMapStore

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