pub struct MmapIndex {
pub path: String,
pub metadata: Metadata,
pub codec: ResidualCodec,
pub ivf: Array1<i64>,
pub ivf_lengths: Array1<i32>,
pub ivf_offsets: Array1<i64>,
pub doc_lengths: Array1<i64>,
pub doc_offsets: Array1<usize>,
pub mmap_codes: MmapNpyArray1I64,
pub mmap_residuals: MmapNpyArray2U8,
}Expand description
A memory-mapped PLAID index for multi-vector search.
This struct uses memory-mapped files for the large arrays (codes and residuals) instead of loading them entirely into RAM. Only small tensors (centroids, bucket weights, IVF) are loaded into memory.
§Memory Usage
Only small tensors (~50 MB for SciFact 5K docs) are loaded into RAM, with code and residual data accessed via OS-managed memory mapping.
§Usage
use next_plaid::MmapIndex;
let index = MmapIndex::load("/path/to/index")?;
let results = index.search(&query, ¶ms, None)?;Fields§
§path: StringPath to the index directory
metadata: MetadataIndex metadata
codec: ResidualCodecResidual codec for quantization/decompression
ivf: Array1<i64>IVF data (concatenated passage IDs per centroid)
ivf_lengths: Array1<i32>IVF lengths (number of passages per centroid)
ivf_offsets: Array1<i64>IVF offsets (cumulative offsets into ivf array)
doc_lengths: Array1<i64>Document lengths (number of tokens per document)
doc_offsets: Array1<usize>Cumulative document offsets for indexing into codes/residuals
mmap_codes: MmapNpyArray1I64Memory-mapped codes array (public for search access)
mmap_residuals: MmapNpyArray2U8Memory-mapped residuals array (public for search access)
Implementations§
Source§impl MmapIndex
impl MmapIndex
Sourcepub fn load(index_path: &str) -> Result<Self>
pub fn load(index_path: &str) -> Result<Self>
Load a memory-mapped index from disk.
This creates merged files for codes and residuals if they don’t exist, then memory-maps them for efficient access.
If the index was created by fast-plaid, it will be automatically converted to next-plaid compatible format on first load.
Sourcepub fn get_candidates(&self, centroid_indices: &[usize]) -> Vec<i64>
pub fn get_candidates(&self, centroid_indices: &[usize]) -> Vec<i64>
Get candidate documents from IVF for given centroid indices.
Sourcepub fn get_document_embeddings(&self, doc_id: usize) -> Result<Array2<f32>>
pub fn get_document_embeddings(&self, doc_id: usize) -> Result<Array2<f32>>
Get document embeddings by decompressing codes and residuals.
Sourcepub fn get_document_codes(&self, doc_ids: &[usize]) -> Vec<Vec<i64>>
pub fn get_document_codes(&self, doc_ids: &[usize]) -> Vec<Vec<i64>>
Get codes for a batch of document IDs (for approximate scoring).
Sourcepub fn decompress_documents(
&self,
doc_ids: &[usize],
) -> Result<(Array2<f32>, Vec<usize>)>
pub fn decompress_documents( &self, doc_ids: &[usize], ) -> Result<(Array2<f32>, Vec<usize>)>
Decompress embeddings for a batch of document IDs.
Sourcepub fn search(
&self,
query: &Array2<f32>,
params: &SearchParameters,
subset: Option<&[i64]>,
) -> Result<SearchResult>
pub fn search( &self, query: &Array2<f32>, params: &SearchParameters, subset: Option<&[i64]>, ) -> Result<SearchResult>
Sourcepub fn search_batch(
&self,
queries: &[Array2<f32>],
params: &SearchParameters,
parallel: bool,
subset: Option<&[i64]>,
) -> Result<Vec<SearchResult>>
pub fn search_batch( &self, queries: &[Array2<f32>], params: &SearchParameters, parallel: bool, subset: Option<&[i64]>, ) -> Result<Vec<SearchResult>>
Sourcepub fn num_documents(&self) -> usize
pub fn num_documents(&self) -> usize
Get the number of documents in the index.
Sourcepub fn num_embeddings(&self) -> usize
pub fn num_embeddings(&self) -> usize
Get the total number of embeddings in the index.
Sourcepub fn num_partitions(&self) -> usize
pub fn num_partitions(&self) -> usize
Get the number of partitions (centroids).
Sourcepub fn avg_doclen(&self) -> f64
pub fn avg_doclen(&self) -> f64
Get the average document length.
Sourcepub fn embedding_dim(&self) -> usize
pub fn embedding_dim(&self) -> usize
Get the embedding dimension.
Sourcepub fn reconstruct(&self, doc_ids: &[i64]) -> Result<Vec<Array2<f32>>>
pub fn reconstruct(&self, doc_ids: &[i64]) -> Result<Vec<Array2<f32>>>
Reconstruct embeddings for specific documents.
This method retrieves the compressed codes and residuals for each document from memory-mapped files and decompresses them to recover the original embeddings.
§Arguments
doc_ids- Slice of document IDs to reconstruct (0-indexed)
§Returns
A vector of 2D arrays, one per document. Each array has shape [num_tokens, dim].
§Example
use next_plaid::MmapIndex;
let index = MmapIndex::load("/path/to/index")?;
let embeddings = index.reconstruct(&[0, 1, 2])?;
for (i, emb) in embeddings.iter().enumerate() {
println!("Document {}: {} tokens x {} dim", i, emb.nrows(), emb.ncols());
}Sourcepub fn create_with_kmeans(
embeddings: &[Array2<f32>],
index_path: &str,
config: &IndexConfig,
) -> Result<Self>
pub fn create_with_kmeans( embeddings: &[Array2<f32>], index_path: &str, config: &IndexConfig, ) -> Result<Self>
Create a new index from document embeddings with automatic centroid computation.
This method:
- Computes centroids using K-means
- Creates index files on disk
- Loads the index using memory-mapped I/O
Note: During creation, data is temporarily held in RAM for processing, then written to disk and loaded as mmap.
§Arguments
embeddings- List of document embeddings, each of shape[num_tokens, dim]index_path- Directory to save the indexconfig- Index configuration
§Returns
The created MmapIndex
Sourcepub fn update(
&mut self,
embeddings: &[Array2<f32>],
config: &UpdateConfig,
) -> Result<Vec<i64>>
pub fn update( &mut self, embeddings: &[Array2<f32>], config: &UpdateConfig, ) -> Result<Vec<i64>>
Update the index with new documents, matching fast-plaid behavior.
This method adds new documents to an existing index with three possible paths:
-
Start-from-scratch mode (num_documents <= start_from_scratch):
- Loads existing embeddings from
embeddings.npyif available - Combines with new embeddings
- Rebuilds the entire index from scratch with fresh K-means
- Clears
embeddings.npyif total exceeds threshold
- Loads existing embeddings from
-
Buffer mode (total_new < buffer_size):
- Adds new documents to the index without centroid expansion
- Saves embeddings to buffer for later centroid expansion
-
Centroid expansion mode (total_new >= buffer_size):
- Deletes previously buffered documents
- Expands centroids with outliers from combined buffer + new embeddings
- Re-indexes all combined embeddings with expanded centroids
§Arguments
embeddings- New document embeddings to addconfig- Update configuration
§Returns
Vector of document IDs assigned to the new embeddings
Sourcepub fn update_with_metadata(
&mut self,
embeddings: &[Array2<f32>],
config: &UpdateConfig,
metadata: Option<&[Value]>,
) -> Result<Vec<i64>>
pub fn update_with_metadata( &mut self, embeddings: &[Array2<f32>], config: &UpdateConfig, metadata: Option<&[Value]>, ) -> Result<Vec<i64>>
Sourcepub fn update_or_create(
embeddings: &[Array2<f32>],
index_path: &str,
index_config: &IndexConfig,
update_config: &UpdateConfig,
) -> Result<(Self, Vec<i64>)>
pub fn update_or_create( embeddings: &[Array2<f32>], index_path: &str, index_config: &IndexConfig, update_config: &UpdateConfig, ) -> Result<(Self, Vec<i64>)>
Update an existing index or create a new one if it doesn’t exist.
§Arguments
embeddings- Document embeddings to addindex_path- Directory for the indexindex_config- Configuration for index creationupdate_config- Configuration for updates
§Returns
A tuple of (MmapIndex, Vec<i64>) containing the index and document IDs
Auto Trait Implementations§
impl Freeze for MmapIndex
impl RefUnwindSafe for MmapIndex
impl Send for MmapIndex
impl Sync for MmapIndex
impl Unpin for MmapIndex
impl UnwindSafe for MmapIndex
Blanket Implementations§
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
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 more