#[cfg(diskann)]
pub(crate) mod diskann;
pub(crate) mod hnsw;
mod mapper;
use std::sync::Arc;
use anyhow::Result;
#[cfg(diskann)]
use crate::catalog::DiskAnnParams;
use crate::catalog::{
DatabaseId, HnswParams, Index, IndexDefinition, NamespaceId, TableDefinition, TableId,
};
use crate::ctx::FrozenContext;
use crate::idx::IndexKeyBase;
#[cfg(diskann)]
use crate::idx::trees::diskann::cache::DiskAnnCache;
use crate::idx::trees::hnsw::cache::VectorCache;
#[cfg(diskann)]
use crate::idx::trees::store::diskann::{DiskAnnIndexes, SharedDiskAnnIndex};
use crate::idx::trees::store::hnsw::{HnswIndexes, SharedHnswIndex};
use crate::idx::trees::store::mapper::Mappers;
#[derive(Clone)]
pub struct IndexStores(Arc<Inner>);
struct Inner {
#[cfg(diskann)]
diskann_indexes: DiskAnnIndexes,
#[cfg(diskann)]
diskann_cache: DiskAnnCache,
hnsw_indexes: HnswIndexes,
mappers: Mappers,
vector_cache: VectorCache,
}
impl IndexStores {
pub(crate) fn new(hnsw_cache_size: u64, diskann_cache_size: u64) -> Self {
#[cfg(not(diskann))]
let _ = diskann_cache_size;
Self(Arc::new(Inner {
#[cfg(diskann)]
diskann_indexes: DiskAnnIndexes::default(),
#[cfg(diskann)]
diskann_cache: DiskAnnCache::new(diskann_cache_size),
hnsw_indexes: HnswIndexes::default(),
mappers: Mappers::default(),
vector_cache: VectorCache::new(hnsw_cache_size),
}))
}
pub(crate) async fn get_index_hnsw(
&self,
ns: NamespaceId,
db: DatabaseId,
ctx: &FrozenContext,
tb: TableId,
ix: &IndexDefinition,
p: &HnswParams,
) -> Result<SharedHnswIndex> {
let ikb = IndexKeyBase::new(ns, db, ix.table_name.clone(), ix.index_id);
self.0.hnsw_indexes.get(ctx, tb, &ikb, p).await
}
#[cfg(diskann)]
pub(crate) async fn get_index_diskann(
&self,
ns: NamespaceId,
db: DatabaseId,
tb: TableId,
ix: &IndexDefinition,
p: &DiskAnnParams,
) -> Result<SharedDiskAnnIndex> {
let ikb = IndexKeyBase::new(ns, db, ix.table_name.clone(), ix.index_id);
self.0.diskann_indexes.get(tb, &ikb, p, self.0.diskann_cache.clone()).await
}
pub(crate) async fn index_removed(
&self,
ns: NamespaceId,
db: DatabaseId,
tb: &TableDefinition,
ix: &IndexDefinition,
) -> Result<()> {
self.remove_index(ns, db, tb.table_id, ix).await
}
async fn remove_index(
&self,
ns: NamespaceId,
db: DatabaseId,
tb: TableId,
ix: &IndexDefinition,
) -> Result<()> {
if matches!(ix.index, Index::Hnsw(_)) {
let ikb = IndexKeyBase::new(ns, db, ix.table_name.clone(), ix.index_id);
self.remove_hnsw_index(tb, ikb).await?;
}
#[cfg(diskann)]
if matches!(ix.index, Index::DiskAnn(_)) {
let ikb = IndexKeyBase::new(ns, db, ix.table_name.clone(), ix.index_id);
self.remove_diskann_index(tb, ikb).await?;
}
Ok(())
}
pub(crate) async fn remove_hnsw_index(&self, tb: TableId, ikb: IndexKeyBase) -> Result<()> {
self.0.hnsw_indexes.remove(tb, &ikb).await?;
self.0.vector_cache.remove_index(ikb.ns(), ikb.db(), tb, ikb.index()).await;
Ok(())
}
#[cfg(diskann)]
pub(crate) async fn remove_diskann_index(&self, tb: TableId, ikb: IndexKeyBase) -> Result<()> {
self.0.diskann_indexes.remove(tb, &ikb).await?;
self.0.diskann_cache.remove_index(ikb.ns(), ikb.db(), tb, ikb.index()).await;
Ok(())
}
pub(crate) fn mappers(&self) -> &Mappers {
&self.0.mappers
}
pub(crate) fn vector_cache(&self) -> &VectorCache {
&self.0.vector_cache
}
}