Skip to main content

Store

Struct Store 

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

Unified storage for tables, graphs, and vectors

UnifiedStore provides a single coherent interface for all data types:

  • Tables: Row-based data with columns
  • Graphs: Nodes and edges with labels
  • Vectors: Embeddings for similarity search

§Features

  • Multi-collection management
  • Cross-collection queries
  • Cross-reference tracking between entities
  • Automatic ID generation
  • Segment-based storage with growing/sealed lifecycle

§Example

use reddb::storage::{Entity, Store};

let store = Store::new();

// Create a collection
store.create_collection("hosts")?;

// Insert an entity
let entity = Entity::table_row(1, "hosts", 1, vec![]);
let id = store.insert("hosts", entity)?;

// Query
let found = store.get("hosts", id);

Implementations§

Source§

impl UnifiedStore

Source

pub fn refresh_collection( &self, name: &str, entities: Vec<UnifiedEntity>, ) -> Result<Vec<Vec<u8>>, StoreError>

Atomic full-collection replace — issue #595 slice 9c.

Builds a fresh SegmentManager populated with entities, atomically swaps it into the collections map, rebuilds the paged B-tree from the same records, and emits a single RefreshCollection WAL action.

Concurrent readers that resolved an Arc<SegmentManager> for this collection before the swap continue reading the prior contents; readers after the swap see the new contents. The transition is single-pointer so partial state is unobservable.

A crash between in-memory mutation and WAL fsync leaves the previous WAL stream intact — on recovery the prior RefreshCollection (or whatever last bulk-applied to the collection) is replayed, so the prior contents are observed.

Source

pub fn refresh_collection_from_records( &self, name: &str, records: Vec<Vec<u8>>, ) -> Result<(), StoreError>

Replica-side analogue of Self::refresh_collection — issue #596 slice 9d. Takes pre-serialized record bytes from the primary’s CDC stream (the same bytes the primary wrote into the RefreshCollection WAL action), applies the atomic swap, and emits the same RefreshCollection WAL action against the replica’s local store WAL so the post-swap state survives a replica restart through the normal recovery path.

Idempotency: re-applying the same records bytes is a full rebuild from the same payload, so the resulting backing- collection contents are equal to the prior call’s result. The primary-side LogicalChangeApplier short-circuits exact duplicate LSN+payload combinations before reaching here.

Source§

impl UnifiedStore

Source

pub fn lookup_graph_nodes_by_label(&self, label: &str) -> Vec<EntityId>

Look up entity IDs for a graph node label across all collections.

Source

pub fn lookup_graph_nodes_by_label_in( &self, collection: &str, label: &str, ) -> Vec<EntityId>

Look up entity IDs for a graph node label scoped to a single collection.

Source

pub fn create_collection( &self, name: impl Into<String>, ) -> Result<(), StoreError>

Source

pub fn get_or_create_collection( &self, name: impl Into<String>, ) -> Arc<SegmentManager>

Get or create a collection

Source

pub fn get_collection(&self, name: &str) -> Option<Arc<SegmentManager>>

Get a collection

Source

pub fn context_index(&self) -> &ContextIndex

Get the context index for cross-structure search.

Source

pub fn take_replayed_turbo_inserts( &self, collection: &str, ) -> Option<Vec<(u64, Vec<f32>)>>

Drain WAL-replayed VectorInsert records for collection (issue #694). Returns None when nothing was captured at open time (in-memory mode, fresh database, or non-turbo collection). One-shot: the caller owns the records after this call, the store’s internal buffer is cleared for that collection.

Source

pub fn set_config_tree(&self, prefix: &str, json: &Value) -> usize

Set multiple config KV pairs at once from a JSON tree. Keys are flattened with dot-notation: {"a":{"b":1}}a.b = 1.

Source

pub fn get_config(&self, key: &str) -> Option<Value>

Read a single config value from red_config by dot-notation key.

Source

pub fn list_collections(&self) -> Vec<String>

List all collections

Source

pub fn drop_collection(&self, name: &str) -> Result<(), StoreError>

Drop a collection

Source

pub fn insert( &self, collection: &str, entity: UnifiedEntity, ) -> Result<EntityId, StoreError>

Insert an entity into a collection

Source

pub fn bulk_insert( &self, collection: &str, entities: Vec<UnifiedEntity>, ) -> Result<Vec<EntityId>, StoreError>

Turbo bulk insert — optimized fast path.

Single lock for the entire batch. Skips bloom filter, memtable, context index, and cross-ref indexing. B-tree writes are batched.

Source

pub fn insert_auto( &self, collection: &str, entity: UnifiedEntity, ) -> Result<EntityId, StoreError>

Insert an entity, creating collection if needed

Source

pub fn get(&self, collection: &str, id: EntityId) -> Option<UnifiedEntity>

Get an entity from a collection

Prefers the live SegmentManager view so reads after update/delete observe the current in-memory state even when the paged B-tree image has not been refreshed yet. Falls back to the B-tree image for recovery-oriented reads.

Source

pub fn get_table_row_by_logical_id( &self, collection: &str, logical_id: EntityId, ) -> Option<UnifiedEntity>

Resolve a table row by stable logical identity.

Legacy rows use logical_id == id, so the physical-id lookup remains the fast path. Versioned rows may have a different physical id and fall back to a scan until the history-store/index slices add a dedicated map.

Source

pub fn table_row_versions_by_logical_id( &self, collection: &str, logical_id: EntityId, ) -> Vec<UnifiedEntity>

Source

pub fn vacuum_mvcc_history( &self, collection: &str, cutoff_xid: u64, ) -> Result<MvccVacuumStats, StoreError>

Source

pub fn get_batch( &self, collection: &str, ids: &[EntityId], ) -> Vec<Option<UnifiedEntity>>

Batch-fetch multiple entities from the same collection in minimal lock acquisitions.

Preferred over N individual get() calls in indexed-scan loops (sorted index, bitmap, hash). Reduces lock acquisitions from N×3 to 2-3 total. Preserves input order: result[i] corresponds to ids[i].

Source

pub fn get_any(&self, id: EntityId) -> Option<(String, UnifiedEntity)>

Get an entity from any collection

Source

pub fn entity_cache_hit_rate(&self) -> Option<f64>

Hit rate of the store’s entity cache (get_any lookups).

Returns None until the cache has served at least one lookup. Exposed for observability — e.g. dashboards distinguishing graph workloads (high hit rate) from OLTP DML (≈ 0 % hit rate).

Source

pub fn entity_cache_stats(&self) -> EntityCacheStats

Snapshot of cache hit / miss / eviction counters and current size.

Source

pub fn delete(&self, collection: &str, id: EntityId) -> Result<bool, StoreError>

Delete an entity

Source

pub fn delete_batch( &self, collection: &str, ids: &[EntityId], ) -> Result<Vec<EntityId>, StoreError>

Source

pub fn set_metadata( &self, collection: &str, id: EntityId, metadata: Metadata, ) -> Result<(), StoreError>

Set metadata for an entity

Source

pub fn get_metadata(&self, collection: &str, id: EntityId) -> Option<Metadata>

Get metadata for an entity

Source

pub fn add_cross_ref( &self, source_collection: &str, source_id: EntityId, target_collection: &str, target_id: EntityId, ref_type: RefType, weight: f32, ) -> Result<(), StoreError>

Add a cross-reference between entities

Source

pub fn get_refs_from(&self, id: EntityId) -> Vec<(EntityId, RefType, String)>

Get cross-references from an entity

Source

pub fn get_refs_to(&self, id: EntityId) -> Vec<(EntityId, RefType, String)>

Get cross-references to an entity

Source

pub fn expand_refs( &self, id: EntityId, depth: u32, ref_types: Option<&[RefType]>, ) -> Vec<(UnifiedEntity, u32, RefType)>

Expand cross-references to get related entities

Source

pub fn unindex_cross_refs_fast_path_hits(&self) -> u64

Test/observability hook: number of times unindex_cross_refs_batch took the read-only fast path. Used to pin the early-exit in tests and as a cheap signal in delete-heavy benchmarks.

Source

pub fn query_all<F>(&self, filter: F) -> Vec<(String, UnifiedEntity)>
where F: Fn(&UnifiedEntity) -> bool + Clone + Send + Sync,

Query across all collections with a filter

Source

pub fn filter_metadata_all( &self, filters: &[(String, MetadataFilter)], ) -> Vec<(String, EntityId)>

Filter by metadata across all collections

Source

pub fn stats(&self) -> StoreStats

Get statistics

Source

pub fn run_maintenance(&self) -> Result<(), StoreError>

Run maintenance on all collections

Source§

impl UnifiedStore

Source

pub fn new() -> UnifiedStore

Source

pub fn format_version(&self) -> u32

Get the current storage format version

Source

pub fn next_entity_id(&self) -> EntityId

Allocate a global entity ID

Source

pub fn reserve_entity_ids(&self, n: u64) -> Range<u64>

Reserve n contiguous global entity IDs with one fetch_add. Caller assigns id = EntityId::new(start + i) per entity.

Source

pub fn load_from_file(path: &Path) -> Result<UnifiedStore, Box<dyn Error>>

Load store from binary file

Binary format:

[magic: 4 bytes "RDST"]
[version: u32]
[collection_count: varu32]
[collections...]
[cross_ref_count: varu32]
[cross_refs...]
Source

pub fn save_to_file(&self, path: &Path) -> Result<(), Box<dyn Error>>

Save store to binary file

Uses compact binary encoding with varint for efficient storage. No JSON - pure binary with pages and indices.

Source§

impl UnifiedStore

Source

pub fn update_physical_file_header( &self, physical: PhysicalFileHeader, ) -> Result<(), StoreError>

Source

pub fn physical_file_header(&self) -> Option<PhysicalFileHeader>

Read the minimal physical header mirrored into page 0 for paged databases.

Source

pub fn write_native_collection_roots( &self, roots: &BTreeMap<String, u64>, existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist native collection roots into a dedicated page in the paged file.

Source

pub fn read_native_collection_roots( &self, page_id: u32, ) -> Result<BTreeMap<String, u64>, StoreError>

Read native collection roots from a dedicated page in the paged file.

Source

pub fn write_native_manifest_summary( &self, sequence: u64, events: &[ManifestEvent], existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist a compact native manifest summary into a dedicated page in the paged file.

Source

pub fn read_native_manifest_summary( &self, page_id: u32, ) -> Result<NativeManifestSummary, StoreError>

Read a compact native manifest summary from a dedicated page in the paged file.

Source

pub fn write_native_registry_summary( &self, summary: &NativeRegistrySummary, existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist a compact native operational registry summary into a dedicated page.

Source§

impl UnifiedStore

Source

pub fn read_native_registry_summary( &self, page_id: u32, ) -> Result<NativeRegistrySummary, StoreError>

Source

pub fn write_native_recovery_summary( &self, summary: &NativeRecoverySummary, existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist a compact native snapshot/export summary into a dedicated page.

Source

pub fn read_native_recovery_summary( &self, page_id: u32, ) -> Result<NativeRecoverySummary, StoreError>

Read a compact native snapshot/export summary from a dedicated page.

Source

pub fn write_native_catalog_summary( &self, summary: &NativeCatalogSummary, existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist a compact native catalog summary into a dedicated page.

Source

pub fn read_native_catalog_summary( &self, page_id: u32, ) -> Result<NativeCatalogSummary, StoreError>

Read a compact native catalog summary from a dedicated page.

Source

pub fn write_native_metadata_state_summary( &self, summary: &NativeMetadataStateSummary, existing_page: Option<u32>, ) -> Result<(u32, u64), StoreError>

Persist a compact native metadata state summary into a dedicated page.

Source

pub fn read_native_metadata_state_summary( &self, page_id: u32, ) -> Result<NativeMetadataStateSummary, StoreError>

Read a compact native metadata state summary from a dedicated page.

Source§

impl UnifiedStore

Source

pub fn read_native_physical_state( &self, ) -> Result<NativePhysicalState, StoreError>

Source

pub fn read_native_blob_chain( &self, root_page: u32, ) -> Result<Vec<u8>, StoreError>

Source

pub fn write_native_vector_artifact_store( &self, artifacts: &[(String, String, Vec<u8>)], existing_page: Option<u32>, ) -> Result<(u32, u64, Vec<NativeVectorArtifactPageSummary>), StoreError>

Source

pub fn read_native_vector_artifact_store( &self, page_id: u32, ) -> Result<Vec<NativeVectorArtifactPageSummary>, StoreError>

Source

pub fn read_native_vector_artifact_blob( &self, page_id: u32, collection: &str, artifact_kind: Option<&str>, ) -> Result<Option<(NativeVectorArtifactPageSummary, Vec<u8>)>, StoreError>

Source§

impl UnifiedStore

Source

pub fn pager(&self) -> Option<&Arc<Pager>>

Get a reference to the underlying pager (if in paged mode).

Source

pub fn config(&self) -> &UnifiedStoreConfig

Borrow the immutable store configuration. Runtime hooks (e.g. the auto_index_id first-insert hook in MutationEngine) read knobs off this struct without going through the legacy global config tree.

Source

pub fn with_config(config: UnifiedStoreConfig) -> UnifiedStore

Source

pub fn open(path: impl AsRef<Path>) -> Result<UnifiedStore, StoreError>

Open or create a page-based database

This uses the page engine for ACID durability with B-tree indices. The database file uses 4KB pages with checksums and efficient caching.

§Arguments
  • path - Path to the database file (e.g., “data.rdb”)
§Example
let store = UnifiedStore::open("security.rdb")?;
store.create_collection("hosts")?;
// ... operations ...
store.persist()?; // Flush to disk
Source

pub fn open_with_config( path: impl AsRef<Path>, config: UnifiedStoreConfig, ) -> Result<UnifiedStore, StoreError>

Source

pub fn persist(&self) -> Result<(), StoreError>

Persist all data to page-based storage

Writes all entities to B-tree pages and flushes to disk. This provides ACID durability guarantees.

Source

pub fn is_paged(&self) -> bool

Check if the store is using page-based persistence

Source

pub fn db_path(&self) -> Option<&Path>

Get the database file path (if using paged mode)

Trait Implementations§

Source§

impl Default for UnifiedStore

Source§

fn default() -> UnifiedStore

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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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> 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<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
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 = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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