pub struct LanceStorageGraph { /* private fields */ }Expand description
Lance-based storage backend for ArrowSpace graph embeddings.
Stores dense and sparse matrices as Lance datasets using a columnar format
(row, col, value for sparse; col_* for dense) schema for efficient
random and columnar access.
Metadata must be seeded before any save_* call so the storage directory
is initialized; the example below is executed as a doc-test on every
cargo test run so it cannot go stale.
§Examples
use genegraph_storage::lance_storage_graph::LanceStorageGraph;
use genegraph_storage::metadata::GeneMetadata;
use genegraph_storage::traits::backend::StorageBackend;
use genegraph_storage::traits::metadata::Metadata;
use smartcore::linalg::basic::arrays::{Array, Array2};
use smartcore::linalg::basic::matrix::DenseMatrix;
let base = std::env::temp_dir().join(format!("genegraph_doc_{}", std::process::id()));
let storage = LanceStorageGraph::new(
base.to_string_lossy().to_string(),
"doc_example".to_string(),
)
.expect("valid instance name");
// some 2D data
let dense: Vec<Vec<f64>> = vec![vec![0.1, 0.4], vec![0.5, 0.2], vec![0.03, 0.8]];
let (nitems, nfeatures) = (dense.len(), dense[0].len());
let data = DenseMatrix::<f64>::from_iterator(
dense.iter().flatten().copied(),
nitems,
nfeatures,
0,
);
// seed metadata FIRST to initialize the storage directory
let md = GeneMetadata::seed_metadata("doc_example", nitems, nfeatures, &storage)
.await
.unwrap();
let md_path = storage.save_metadata(&md).await.unwrap();
// your data is saved in an efficient Lance format
storage.save_dense("my_dataset", &data, &md_path).await.unwrap();
// Loading back
let loaded = storage.load_dense("my_dataset").await.unwrap();
assert_eq!(loaded.shape(), (nitems, nfeatures));Implementations§
Source§impl LanceStorageGraph
impl LanceStorageGraph
Sourcepub fn new(base: String, name: String) -> StorageResult<Self>
pub fn new(base: String, name: String) -> StorageResult<Self>
Creates a new Lance storage backend.
This is used for on-the-fly creation. For proper setup use Genefold<...>::seed.
§Arguments
base- Base directory path for all storage filesname- Name prefix for this storage instance
The name must not carry the reserved generation suffix __g<n>
(#117-3): only Self::scoped_generation mints generation-qualified
names, otherwise generation discovery and sweep would treat the
instance as a generation of another logical dataset.
Sourcepub async fn spawn(
base_path: String,
) -> Result<(Self, GeneMetadata), StorageError>
pub async fn spawn( base_path: String, ) -> Result<(Self, GeneMetadata), StorageError>
Spawn a LanceStorage from an existing seeded directory (with metadata.json)
Sourcepub fn scoped_generation(&self, generation: u64) -> Self
pub fn scoped_generation(&self, generation: u64) -> Self
A handle over generation gen of this logical dataset: artifact
paths resolve as {logical}__g{gen}_{key}.lance and the metadata
path as {logical}__g{gen}_metadata.json — the per-generation
commit pointer (#93, RFC #81-P5). The logical identity stays
recoverable via crate::generations::logical_name.
Trait Implementations§
Source§impl Clone for LanceStorageGraph
impl Clone for LanceStorageGraph
Source§fn clone(&self) -> LanceStorageGraph
fn clone(&self) -> LanceStorageGraph
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl ClusteringArtifacts for LanceStorageGraph
impl ClusteringArtifacts for LanceStorageGraph
Source§async fn save_centroid_map(
&self,
map: &[usize],
md_path: &Path,
) -> StorageResult<()>
async fn save_centroid_map( &self, map: &[usize], md_path: &Path, ) -> StorageResult<()>
Save centroid_map (item-to-centroid assignments)
Source§async fn load_centroid_map(&self) -> StorageResult<Vec<usize>>
async fn load_centroid_map(&self) -> StorageResult<Vec<usize>>
Load centroid_map
Source§async fn save_subcentroid_lambdas(
&self,
lambdas: &[f64],
md_path: &Path,
) -> StorageResult<()>
async fn save_subcentroid_lambdas( &self, lambdas: &[f64], md_path: &Path, ) -> StorageResult<()>
Save subcentroid_lambdas (tau values for subcentroids)
Source§async fn load_subcentroid_lambdas(&self) -> StorageResult<Vec<f64>>
async fn load_subcentroid_lambdas(&self) -> StorageResult<Vec<f64>>
Load subcentroid_lambdas
Source§async fn save_subcentroids(
&self,
subcentroids: &DenseMatrix<f64>,
md_path: &Path,
) -> StorageResult<()>
async fn save_subcentroids( &self, subcentroids: &DenseMatrix<f64>, md_path: &Path, ) -> StorageResult<()>
Save subcentroids (dense matrix)
Source§async fn load_subcentroids(&self) -> StorageResult<Vec<Vec<f64>>>
async fn load_subcentroids(&self) -> StorageResult<Vec<Vec<f64>>>
Load subcentroids as Vec<Vec
Source§async fn save_item_norms(
&self,
item_norms: &[f64],
md_path: &Path,
) -> StorageResult<()>
async fn save_item_norms( &self, item_norms: &[f64], md_path: &Path, ) -> StorageResult<()>
Save item norms vector
Source§async fn load_item_norms(&self) -> StorageResult<Vec<f64>>
async fn load_item_norms(&self) -> StorageResult<Vec<f64>>
Load item norms vector
Source§async fn save_cluster_assignments(
&self,
assignments: &[Option<usize>],
md_path: &Path,
) -> StorageResult<()>
async fn save_cluster_assignments( &self, assignments: &[Option<usize>], md_path: &Path, ) -> StorageResult<()>
Source§async fn load_cluster_assignments(&self) -> StorageResult<Vec<Option<usize>>>
async fn load_cluster_assignments(&self) -> StorageResult<Vec<Option<usize>>>
Source§impl Debug for LanceStorageGraph
impl Debug for LanceStorageGraph
Source§impl LanceStorage for LanceStorageGraph
impl LanceStorage for LanceStorageGraph
Source§async fn write_lance_batch_async(
&self,
uri: String,
batch: RecordBatch,
) -> StorageResult<()>
async fn write_lance_batch_async( &self, uri: String, batch: RecordBatch, ) -> StorageResult<()>
Source§async fn read_lance_all_batches_async(
&self,
uri: String,
) -> StorageResult<RecordBatch>
async fn read_lance_all_batches_async( &self, uri: String, ) -> StorageResult<RecordBatch>
Source§async fn save_primitive_column<T: ArrowPrimitiveType>(
&self,
key: &str,
field_name: &str,
values: Vec<T::Native>,
md_path: &Path,
) -> StorageResult<()>where
Self: StorageBackend,
async fn save_primitive_column<T: ArrowPrimitiveType>(
&self,
key: &str,
field_name: &str,
values: Vec<T::Native>,
md_path: &Path,
) -> StorageResult<()>where
Self: StorageBackend,
<name>_<key>.lance and registers it in the metadata files map under
key with filetype “vector” and shape (<len>, 1). Read moreSource§impl StorageBackend for LanceStorageGraph
impl StorageBackend for LanceStorageGraph
Source§fn basepath_to_uri(&self) -> StorageResult<String>
fn basepath_to_uri(&self) -> StorageResult<String>
Converts the base path for the store to a file:// URI for Lance.
Source§async fn save_dense(
&self,
key: &str,
matrix: &DenseMatrix<f64>,
md_path: &Path,
) -> StorageResult<()>
async fn save_dense( &self, key: &str, matrix: &DenseMatrix<f64>, md_path: &Path, ) -> StorageResult<()>
Save dense matrix using Lance-optimized vector format.
Each row of the matrix becomes a FixedSizeList entry for efficient vector operations. This format is optimized for vector search and enables Lance’s full-zip encoding.
§Arguments
filename- any namematrix- Dense matrix to save (N rows × F cols)md_path- Metadata file path for validation
Source§async fn load_dense(&self, key: &str) -> StorageResult<DenseMatrix<f64>>
async fn load_dense(&self, key: &str) -> StorageResult<DenseMatrix<f64>>
Source§async fn load_dense_from_file(
&self,
path: &Path,
) -> StorageResult<DenseMatrix<f64>>
async fn load_dense_from_file( &self, path: &Path, ) -> StorageResult<DenseMatrix<f64>>
Load initial data using columnar format from a file path.
Async test helper that avoids any internal blocking runtimes. Format dispatch only (#117-4): each branch lives in its own helper.
Source§async fn save_dense_to_file(
data: &DenseMatrix<f64>,
path: &Path,
) -> StorageResult<()>
async fn save_dense_to_file( data: &DenseMatrix<f64>, path: &Path, ) -> StorageResult<()>
Save dense matrix to file in columnar format (col_0, col_1, …, col_N)
Async test helper that avoids any internal blocking runtimes.
Source§fn metadata_path(&self) -> PathBuf
fn metadata_path(&self) -> PathBuf
Source§fn file_path(&self, key: &str) -> PathBuf
fn file_path(&self, key: &str) -> PathBuf
Source§async fn save_sparse(
&self,
key: &str,
matrix: &CsMat<f64>,
md_path: &Path,
) -> StorageResult<()>
async fn save_sparse( &self, key: &str, matrix: &CsMat<f64>, md_path: &Path, ) -> StorageResult<()>
Source§async fn load_sparse(&self, key: &str) -> StorageResult<CsMat<f64>>
async fn load_sparse(&self, key: &str) -> StorageResult<CsMat<f64>>
Source§async fn save_lambdas(
&self,
lambdas: &[f64],
md_path: &Path,
) -> StorageResult<()>
async fn save_lambdas( &self, lambdas: &[f64], md_path: &Path, ) -> StorageResult<()>
Source§async fn load_lambdas(&self) -> StorageResult<Vec<f64>>
async fn load_lambdas(&self) -> StorageResult<Vec<f64>>
Source§async fn save_vector(
&self,
key: &str,
vector: &[f64],
md_path: &Path,
) -> StorageResult<()>
async fn save_vector( &self, key: &str, vector: &[f64], md_path: &Path, ) -> StorageResult<()>
Source§async fn save_index(
&self,
key: &str,
vector: &[usize],
md_path: &Path,
) -> StorageResult<()>
async fn save_index( &self, key: &str, vector: &[usize], md_path: &Path, ) -> StorageResult<()>
async fn load_vector(&self, filename: &str) -> StorageResult<Vec<f64>>
Source§async fn load_index(&self, filename: &str) -> StorageResult<Vec<usize>>
async fn load_index(&self, filename: &str) -> StorageResult<Vec<usize>>
Source§async fn save_vectors_with(
&self,
name: &str,
batch: &RecordBatch,
properties: &BTreeMap<String, String>,
md_path: &Path,
) -> StorageResult<()>
async fn save_vectors_with( &self, name: &str, batch: &RecordBatch, properties: &BTreeMap<String, String>, md_path: &Path, ) -> StorageResult<()>
graph linkage of RFC #81-P4: properties.graph = <name>).Source§async fn load_vectors(&self, name: &str) -> StorageResult<RecordBatch>
async fn load_vectors(&self, name: &str) -> StorageResult<RecordBatch>
RecordBatch with its
original schema (including collection metadata).Source§async fn save_graph_with(
&self,
name: &str,
edges: &[GraphEdge],
options: &GraphWriteOptions,
md_path: &Path,
) -> StorageResult<()>
async fn save_graph_with( &self, name: &str, edges: &[GraphEdge], options: &GraphWriteOptions, md_path: &Path, ) -> StorageResult<()>
Source§async fn load_graph(&self, name: &str) -> StorageResult<StoredGraph>
async fn load_graph(&self, name: &str) -> StorageResult<StoredGraph>
StoredGraph::to_csr.Source§async fn save_vectors_to_path(
&self,
path: &Path,
batch: &RecordBatch,
properties: &BTreeMap<String, String>,
) -> StorageResult<()>
async fn save_vectors_to_path( &self, path: &Path, batch: &RecordBatch, properties: &BTreeMap<String, String>, ) -> StorageResult<()>
path
without touching the metadata registry (#106): the batch is
validated, stamped with dataset-level collection metadata
(including user properties) and written; parent directories are
created as needed. Registry ownership stays with the caller — the
counterpart of Self::save_vectors_with for consumers that run
their own metadata registry (e.g. an ArrowSpaceMetadata commit
pointer at the instance metadata path). No GeneMetadata read or
write occurs.Source§async fn load_vectors_from_path(
&self,
path: &Path,
) -> StorageResult<RecordBatch>
async fn load_vectors_from_path( &self, path: &Path, ) -> StorageResult<RecordBatch>
path
(registry-free): the path-based counterpart of
Self::load_vectors.Source§async fn save_graph_to_path(
&self,
path: &Path,
edges: &[GraphEdge],
options: &GraphWriteOptions,
) -> StorageResult<()>
async fn save_graph_to_path( &self, path: &Path, edges: &[GraphEdge], options: &GraphWriteOptions, ) -> StorageResult<()>
path without
touching the metadata registry (#106); see
Self::save_graph_with for the options and
Self::save_vectors_to_path for the registry-free contract.Source§async fn load_graph_from_path(&self, path: &Path) -> StorageResult<StoredGraph>
async fn load_graph_from_path(&self, path: &Path) -> StorageResult<StoredGraph>
path
(registry-free): the path-based counterpart of Self::load_graph.Source§async fn load_graph_from_path_with_options(
&self,
path: &Path,
options: &GraphReadOptions,
) -> StorageResult<StoredGraph>
async fn load_graph_from_path_with_options( &self, path: &Path, options: &GraphReadOptions, ) -> StorageResult<StoredGraph>
path with read options
(#108): strict mode rejects datasets without a num_nodes stamp
(and, optionally, validates column names) instead of silently
resizing to max_id + 1. The tolerant default is the compat shim.Source§async fn load_scalars(&self, name: &str) -> StorageResult<Vec<f64>>
async fn load_scalars(&self, name: &str) -> StorageResult<Vec<f64>>
Float64|Float32 column, e.g.
lambdas or norms — as Vec<f64> (#106); f32 values are upcast
losslessly. The stamped dataset kind must be vector-space
(missing or mismatched kinds are rejected: physical shape
determines decodability, the logical kind determines semantic
validity), making every kind=vector-space collection uniformly
loadable instead of requiring the legacy fixed-key readers.Source§async fn save_scalars_to_path(
&self,
path: &Path,
values: &[f64],
) -> StorageResult<()>
async fn save_scalars_to_path( &self, path: &Path, values: &[f64], ) -> StorageResult<()>
Float64 column
(e.g. lambdas or norms) — at an explicit path without touching the
metadata registry (#107): the dataset is stamped kind=vector-space
and parent directories are created as needed. Registry ownership
stays with the caller; no GeneMetadata read or write occurs. The
counterpart of Self::save_vectors_to_path for scalar-only
collections (which save_vectors_to_path cannot write, as its
schema validation requires a FixedSizeList column).Source§async fn load_scalars_from_path(&self, path: &Path) -> StorageResult<Vec<f64>>
async fn load_scalars_from_path(&self, path: &Path) -> StorageResult<Vec<f64>>
path (registry-free):
the path-based counterpart of Self::load_scalars, with the same
kind gate. load_scalars delegates to this.Source§async fn collection_schema_from_path(
&self,
path: &Path,
) -> StorageResult<Schema>
async fn collection_schema_from_path( &self, path: &Path, ) -> StorageResult<Schema>
path without decoding any column buffers (#109): the
backend surface of crate::lancefmt::read_schema, so consumers
doing kind/stamp gating don’t pay a full columnar scan.Source§fn exists(path: &str) -> (bool, Option<PathBuf>)
fn exists(path: &str) -> (bool, Option<PathBuf>)
true and the path to the metadata file if metadata file exists and is valid,
false otherwise.
This is used to avoid overwriting existing indexes.Source§fn path_to_uri(path: &Path) -> StorageResult<String>
fn path_to_uri(path: &Path) -> StorageResult<String>
file:// URI for Lance. Read moreSource§fn validate_initialized(&self, md_path: &Path) -> StorageResult<()>
fn validate_initialized(&self, md_path: &Path) -> StorageResult<()>
Source§fn to_dense_record_batch(
&self,
matrix: &DenseMatrix<f64>,
) -> Result<RecordBatch, StorageError>
fn to_dense_record_batch( &self, matrix: &DenseMatrix<f64>, ) -> Result<RecordBatch, StorageError>
Source§fn from_dense_record_batch(
&self,
batch: &RecordBatch,
) -> Result<DenseMatrix<f64>, StorageError>
fn from_dense_record_batch( &self, batch: &RecordBatch, ) -> Result<DenseMatrix<f64>, StorageError>
Source§fn to_sparse_record_batch(&self, m: &CsMat<f64>) -> StorageResult<RecordBatch>
fn to_sparse_record_batch(&self, m: &CsMat<f64>) -> StorageResult<RecordBatch>
Source§fn from_sparse_record_batch(
&self,
batch: RecordBatch,
expected_rows: usize,
expected_cols: usize,
) -> StorageResult<CsMat<f64>>
fn from_sparse_record_batch( &self, batch: RecordBatch, expected_rows: usize, expected_cols: usize, ) -> StorageResult<CsMat<f64>>
Source§async fn save_metadata(&self, metadata: &GeneMetadata) -> StorageResult<PathBuf>
async fn save_metadata(&self, metadata: &GeneMetadata) -> StorageResult<PathBuf>
Source§async fn load_metadata(&self) -> StorageResult<GeneMetadata>
async fn load_metadata(&self) -> StorageResult<GeneMetadata>
Source§async fn save_vectors(
&self,
name: &str,
batch: &RecordBatch,
md_path: &Path,
) -> StorageResult<()>
async fn save_vectors( &self, name: &str, batch: &RecordBatch, md_path: &Path, ) -> StorageResult<()>
Self::save_vectors_with. Read moreSource§async fn save_graph(
&self,
name: &str,
edges: &[GraphEdge],
md_path: &Path,
) -> StorageResult<()>
async fn save_graph( &self, name: &str, edges: &[GraphEdge], md_path: &Path, ) -> StorageResult<()>
u32 node ids
(the default width) and f64 weights (the default width, mirroring
the sparse-matrix value column). Ids above u32::MAX surface
StorageError::Overflow instead of being truncated. Weights are
persisted faithfully (normalization transforms belong to the
producer); the opt-in GraphWriteOptions::weight_range asserts
compliance with a declared closed interval, and weights that cannot
be stored exactly at an explicitly declared
crate::graph::WeightType::F32 width are rejected instead of
being silently narrowed. Read moreSource§async fn load_graph_from_path_strict(
&self,
path: &Path,
) -> StorageResult<StoredGraph>
async fn load_graph_from_path_strict( &self, path: &Path, ) -> StorageResult<StoredGraph>
Self::load_graph_from_path (#108): rejects
datasets without a num_nodes stamp with a typed
StorageError::Invalid and validates the src/dst/weight
column names, so pre-collections triplet artifacts are positively
identified rather than positionally coerced. Read moreSource§async fn collection_schema(&self, name: &str) -> StorageResult<Schema>
async fn collection_schema(&self, name: &str) -> StorageResult<Schema>
Self::collection_schema_from_path.Source§async fn verify_collection_from_path(
&self,
path: &Path,
expected: &DatasetFacts,
) -> StorageResult<()>
async fn verify_collection_from_path( &self, path: &Path, expected: &DatasetFacts, ) -> StorageResult<()>
path
against expected (#115): reads the schema footer via
crate::lancefmt::read_schema — no column buffers are decoded —
and cross-checks the facts (kind, rows/cols, num_nodes,
weight width). Mismatches surface as typed errors naming the fact. Read moreSource§async fn verify_collection(
&self,
name: &str,
expected: &DatasetFacts,
) -> StorageResult<()>
async fn verify_collection( &self, name: &str, expected: &DatasetFacts, ) -> StorageResult<()>
Self::verify_collection_from_path,
resolving through Self::file_path.Auto Trait Implementations§
impl Freeze for LanceStorageGraph
impl RefUnwindSafe for LanceStorageGraph
impl Send for LanceStorageGraph
impl Sync for LanceStorageGraph
impl Unpin for LanceStorageGraph
impl UnsafeUnpin for LanceStorageGraph
impl UnwindSafe for LanceStorageGraph
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§unsafe fn to_subset_unchecked(&self) -> SS
unsafe fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.