iqdb-index 0.3.0

The Index trait unifying flat, HNSW, and IVF vector indexes - part of the iQDB family.
Documentation
  • IndexCore trait — the object-safe operational surface (insert, delete, search, len, dim, metric, flush, stats). The engine holds indexes as Box<dyn IndexCore>.
  • Index trait — typed construction: an associated Config and a new(dim, metric, config). Split out from IndexCore because a Self-returning constructor is not object-safe.
  • Associated Config — each index exposes its own parameter struct, not a god-config enum.
  • Default batch shimsinsert_batch / search_batch ship for free and are overridable when a backend has a vectorized fast path.
  • IndexStats — uniform, allocation-light introspection across index types.
  • Documented contracts — best-first ordering (with the DotProduct negation rule), deletion visibility, and the Send + Sync concurrency model live on the trait, so every backend agrees.

Installation

[dependencies]
iqdb-index = "0.3"

Quick Start

Implement the two traits for your index, then construct, insert, and search through one uniform surface. The full runnable version is in examples/custom_index.rs.

use std::sync::Arc;
use iqdb_index::{Index, IndexCore};
use iqdb_types::{DistanceMetric, SearchParams, VectorId};

// `FlatIndex` implements `IndexCore` + `Index` (see the example).
let mut index = FlatIndex::new(3, DistanceMetric::Euclidean, FlatConfig)?;

index.insert_batch(vec![
    (VectorId::from(1u64), Arc::from([1.0, 0.0, 0.0].as_slice()), None),
    (VectorId::from(2u64), Arc::from([0.0, 1.0, 0.0].as_slice()), None),
])?;

let hits = index.search(&[1.0, 0.0, 0.0], &SearchParams::new(1, DistanceMetric::Euclidean))?;
assert_eq!(hits[0].id, VectorId::U64(1)); // best-first

// Hold any backend behind the object-safe trait:
let engine: Vec<Box<dyn IndexCore>> = vec![Box::new(index)];
assert_eq!(engine[0].len(), 2);

The three tiers

Tier Surface When
Tier 1 Index::new + the IndexCore operations Build an index and use it.
Tier 2 Index::Config Tune a specific backend.
Tier 3 implement IndexCore + Index Add a new index strategy.

Status

v0.3.0 — the trait surface, validated against the real index families. IndexCore, Index, IndexStats, and the default batch shims are implemented, documented with runnable examples, and property-tested (best-first ordering, deletion visibility, batch == loop). The surface is cross-checked against the live iqdb-flat (brute-force), iqdb-hnsw (graph), and iqdb-ivf (clustered) implementations — each implements the traits verbatim with its own Config — and a consumer-simulation suite proves all three coexist behind Box<dyn IndexCore> (DIRECTIVES §8). No API change was needed. Remaining 0.x work — the async decision and the API freeze — is tracked in the ROADMAP. Full surface in docs/API.md.

Where It Fits

iqdb-index is the interface every index speaks. It is implemented by:

  • iqdb-types — the only dependency
  • iqdb-flat / iqdb-hnsw / iqdb-ivf — implement this trait
  • iqdb-build / iqdb-eval / iqdb — are generic over it

Designing this trait so flat, HNSW, and IVF all fit cleanly is the crate's whole job.

Contributing

See dev/DIRECTIVES.md for engineering standards and the definition of done. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.