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
impl HashMapStore
pub fn new() -> Self
Sourcepub fn snapshot(&self) -> HashMapStoreSnapshot
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.)
Sourcepub fn freeze(&self) -> HashMapStore
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.
Sourcepub fn restore(&self, snap: &HashMapStoreSnapshot)
pub fn restore(&self, snap: &HashMapStoreSnapshot)
Restore from a savepoint snapshot.
Sourcepub fn create_savepoint(&self) -> u64
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.
Sourcepub fn restore_savepoint(&self, savepoint_id: u64)
pub fn restore_savepoint(&self, savepoint_id: u64)
Restore the store to a previously created savepoint.
Sourcepub fn discard_savepoint(&self, savepoint_id: u64)
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).
Sourcepub fn restore_without_counters(&self, snap: &HashMapStoreSnapshot)
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.
Sourcepub fn store_snapshot(&self) -> StoreSnapshot
pub fn store_snapshot(&self) -> StoreSnapshot
Create a type-erased store snapshot for undo.
Sourcepub fn restore_store_snapshot(&self, snap: &StoreSnapshot)
pub fn restore_store_snapshot(&self, snap: &StoreSnapshot)
Restore from a type-erased store snapshot (preserves counters).
Sourcepub fn check_junction_indexes(&self) -> Result<(), String>
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.