use bitcode::{Decode, Encode};
#[derive(Debug, Clone, Encode, Decode)]
pub struct IndexManifest {
pub magic: [u8; 4],
pub version: u16,
pub created_at: i64,
pub last_modified: i64,
pub lsn: u64,
pub vector_indexes: Vec<VectorIndexManifestEntry>,
pub graph_index: Option<GraphIndexManifestEntry>,
pub temporal_index: Option<TemporalIndexManifestEntry>,
pub temporal_adjacency_index: Option<TemporalAdjacencyIndexManifestEntry>,
pub string_interner: Option<StringInternerManifestEntry>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct VectorIndexManifestEntry {
pub property_name: String,
pub dimensions: u32,
pub metric: u8,
pub current_file: String,
pub mappings_file: String,
pub snapshot_count: u32,
pub temporal_enabled: bool,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct GraphIndexManifestEntry {
pub adjacency_file: String,
pub node_count: u64,
pub edge_count: u64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct TemporalIndexManifestEntry {
pub node_versions_file: String,
pub edge_versions_file: String,
pub version_count: u64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct StringInternerManifestEntry {
pub interner_file: String,
pub string_count: u64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct TemporalAdjacencyIndexManifestEntry {
pub adjacency_file: String,
pub entry_count: u64,
pub node_count: u64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct StringInternerData {
pub magic: [u8; 4],
pub version: u16,
pub string_count: u64,
pub strings: Vec<String>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct GraphIndexData {
pub magic: [u8; 4],
pub version: u16,
pub node_count: u64,
pub edge_count: u64,
pub nodes: Vec<PersistedNode>,
pub edges: Vec<PersistedEdge>,
pub outgoing_node_ids: Vec<u64>,
pub outgoing_offsets: Vec<u64>,
pub outgoing_neighbors: Vec<u64>,
pub incoming_node_ids: Vec<u64>,
pub incoming_offsets: Vec<u64>,
pub incoming_neighbors: Vec<u64>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct GraphIndexDelta {
pub magic: [u8; 4],
pub version: u16,
pub added_nodes: Vec<PersistedNode>,
pub modified_nodes: Vec<PersistedNode>,
pub deleted_node_ids: Vec<u64>,
pub added_edges: Vec<PersistedEdge>,
pub modified_edges: Vec<PersistedEdge>,
pub deleted_edge_ids: Vec<u64>,
pub new_node_count: u64,
pub new_edge_count: u64,
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
pub struct PersistedNode {
pub id: u64,
pub label_idx: u32,
pub version_id: u64,
pub properties: PersistedPropertyMap,
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
pub struct PersistedEdge {
pub id: u64,
pub source_id: u64,
pub target_id: u64,
pub label_idx: u32,
pub version_id: u64,
pub properties: PersistedPropertyMap,
}
#[derive(Debug, Clone, Default, PartialEq, Encode, Decode)]
pub struct PersistedPropertyMap {
pub entries: Vec<(u32, PersistedPropertyValue)>,
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
pub enum PersistedPropertyValue {
Null,
Bool(bool),
Int(i64),
Float(f64),
String(u32),
Bytes(Vec<u8>),
Vector(Vec<f32>),
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct TemporalIndexData {
pub magic: [u8; 4],
pub version: u16,
pub node_versions: Vec<NodeVersionEntry>,
pub node_anchors: Vec<NodeAnchorEntry>,
pub edge_versions: Vec<EdgeVersionEntry>,
pub edge_anchors: Vec<EdgeAnchorEntry>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct NodeVersionEntry {
pub version_id: u64,
pub node_id: u64,
pub label_idx: u32,
pub valid_from: i64,
pub valid_to: Option<i64>,
pub valid_from_logical: u32,
pub valid_to_logical: Option<u32>,
pub tx_time: i64,
pub tx_time_logical: u32,
pub version_type: PersistedVersionType,
pub properties: PersistedPropertyMap,
pub vector_snapshot_id: Option<u64>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct NodeAnchorEntry {
pub node_id: u64,
pub anchor_tx_time: i64,
pub full_state: PersistedPropertyMap,
pub vector_snapshot_id: Option<u64>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub enum PersistedVersionType {
Delta {
base_anchor_tx: i64,
base_anchor_tx_logical: u32,
removed_keys: Vec<u32>,
},
Anchor,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct EdgeVersionEntry {
pub version_id: u64,
pub edge_id: u64,
pub source_id: u64,
pub target_id: u64,
pub label_idx: u32,
pub valid_from: i64,
pub valid_to: Option<i64>,
pub valid_from_logical: u32,
pub valid_to_logical: Option<u32>,
pub tx_time: i64,
pub tx_time_logical: u32,
pub version_type: PersistedVersionType,
pub properties: PersistedPropertyMap,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct EdgeAnchorEntry {
pub edge_id: u64,
pub anchor_tx_time: i64,
pub full_state: PersistedPropertyMap,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct TemporalAdjacencyData {
pub magic: [u8; 4],
pub version: u16,
pub outgoing: Vec<NodeAdjacencyEntry>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct NodeAdjacencyEntry {
pub node_id: u64,
pub entries: Vec<PersistedTemporalAdjacencyEntry>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct PersistedTemporalAdjacencyEntry {
pub edge_id: u64,
pub neighbor: u64,
pub label: u32,
pub valid_from_wallclock: i64,
pub valid_from_logical: u32,
pub valid_to_wallclock: i64,
pub valid_to_logical: u32,
pub tx_from_wallclock: i64,
pub tx_from_logical: u32,
pub tx_to_wallclock: i64,
pub tx_to_logical: u32,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct VectorIndexMeta {
pub magic: [u8; 4],
pub version: u16,
pub property_name: String,
pub dimensions: u32,
pub metric: u8,
pub hnsw_config: PersistedHnswConfig,
pub vector_count: u64,
pub created_at: i64,
pub last_modified: i64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct PersistedHnswConfig {
pub m: u16,
pub ef_construction: u16,
pub ef_search: u16,
}
#[derive(Debug, Clone)]
pub struct VectorIndexData {
pub meta: VectorIndexMeta,
pub mappings: VectorMappingsData,
pub index_path: std::path::PathBuf,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct VectorMappingsData {
pub version: u16,
pub count: u64,
pub mappings: Vec<VectorMapping>,
pub deleted_ids: Vec<u64>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct VectorMapping {
pub node_id: u64,
pub usearch_key: u64,
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct VectorSnapshotMeta {
pub snapshot_id: u64,
pub snapshot_type: PersistedSnapshotType,
pub timestamp: i64,
pub vector_count: u64,
pub config: PersistedHnswConfig,
pub base_snapshot_id: Option<u64>,
}
#[derive(Debug, Clone, Encode, Decode)]
pub enum PersistedSnapshotType {
Full,
Delta {
changes_count: u64,
},
}
#[derive(Debug, Clone, PartialEq, Default, Encode, Decode)]
#[cfg_attr(feature = "config-toml", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "config-toml", serde(default))]
pub struct PersistencePolicies {
pub vector: VectorPersistencePolicy,
pub graph: GraphPersistencePolicy,
pub temporal: TemporalPersistencePolicy,
pub strings: StringPersistencePolicy,
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "config-toml", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "config-toml", serde(default))]
pub struct VectorPersistencePolicy {
pub mutation_threshold: u32,
pub time_interval_secs: u32,
}
impl Default for VectorPersistencePolicy {
fn default() -> Self {
Self {
mutation_threshold: 1000,
time_interval_secs: 300, }
}
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "config-toml", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "config-toml", serde(default))]
pub struct GraphPersistencePolicy {
pub on_adjacency_rebuild: bool,
pub mutation_threshold: u32,
pub time_interval_secs: u32,
}
impl Default for GraphPersistencePolicy {
fn default() -> Self {
Self {
on_adjacency_rebuild: true,
mutation_threshold: 5000,
time_interval_secs: 600, }
}
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "config-toml", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "config-toml", serde(default))]
pub struct TemporalPersistencePolicy {
pub version_threshold: u32,
pub anchor_threshold: u32,
pub time_interval_secs: u32,
}
impl Default for TemporalPersistencePolicy {
fn default() -> Self {
Self {
version_threshold: 1000,
anchor_threshold: 100,
time_interval_secs: 300, }
}
}
#[derive(Debug, Clone, PartialEq, Encode, Decode)]
#[cfg_attr(feature = "config-toml", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "config-toml", serde(default))]
pub struct StringPersistencePolicy {
pub new_strings_threshold: u32,
pub time_interval_secs: u32,
}
impl Default for StringPersistencePolicy {
fn default() -> Self {
Self {
new_strings_threshold: 500,
time_interval_secs: 600, }
}
}