semantic_memory/storage.rs
1//! Storage path management for the memory directory convention.
2//!
3//! A memory store lives in a directory containing:
4//! - `memory.db` — SQLite database (content, metadata, FTS5, f32 embeddings)
5//! - `memory.hnsw.graph` — HNSW graph topology (when `hnsw` feature enabled)
6//! - `memory.hnsw.data` — HNSW vector data (when `hnsw` feature enabled)
7
8use std::path::{Path, PathBuf};
9
10/// Resolved file paths for all storage files within a memory directory.
11#[derive(Debug, Clone)]
12pub struct StoragePaths {
13 /// The base directory containing all storage files.
14 pub base_dir: PathBuf,
15 /// Path to the SQLite database file.
16 pub sqlite_path: PathBuf,
17 /// Directory for HNSW files (same as base_dir, hnsw_rs writes basename.hnsw.graph + basename.hnsw.data).
18 pub hnsw_dir: PathBuf,
19 /// Base name for HNSW files (e.g., "memory" → memory.hnsw.graph + memory.hnsw.data).
20 pub hnsw_basename: String,
21}
22
23impl StoragePaths {
24 /// Create storage paths from a base directory.
25 ///
26 /// Given `/path/to/memory`, resolves:
27 /// - `/path/to/memory/memory.db`
28 /// - `/path/to/memory/memory.hnsw.graph`
29 /// - `/path/to/memory/memory.hnsw.data`
30 pub fn new(base_dir: impl AsRef<Path>) -> Self {
31 let base_dir = base_dir.as_ref().to_path_buf();
32 Self {
33 sqlite_path: base_dir.join("memory.db"),
34 hnsw_dir: base_dir.clone(),
35 hnsw_basename: "memory".to_string(),
36 base_dir,
37 }
38 }
39
40 /// Path to the HNSW graph file.
41 pub fn hnsw_graph_path(&self) -> PathBuf {
42 self.base_dir
43 .join(format!("{}.hnsw.graph", self.hnsw_basename))
44 }
45
46 /// Path to the HNSW data file.
47 pub fn hnsw_data_path(&self) -> PathBuf {
48 self.base_dir
49 .join(format!("{}.hnsw.data", self.hnsw_basename))
50 }
51
52 /// Whether both HNSW sidecar files exist on disk.
53 pub fn hnsw_files_exist(&self) -> bool {
54 self.hnsw_graph_path().exists() && self.hnsw_data_path().exists()
55 }
56}