# iqdb-build v0.2.0 — The sequential builder

**The first working construction path.** v0.2.0 turns the scaffold into a usable
library: a single generic builder that constructs any iQDB index from a batch of
vectors, plus the one-call free functions that cover the common case. This is the
foundation the parallel, merge, and concurrent paths are built on across the rest
of the 0.x series — landed first, and landed verified.

## What is iqdb-build?

The bulk-construction layer of the iQDB vector database. Loading a million
vectors into an index one `insert` at a time is slow; `iqdb-build` is the fast
path. It is **generic over** `iqdb_index::Index`, so the same builder constructs
a flat, HNSW, or IVF index — or a backend of your own — without ever naming a
concrete type. It sits above `iqdb-types` and `iqdb-index` and is consumed by
`iqdb` for bulk ingestion.

## What's in 0.2.0

- **`IndexBuilder<I>`** — a configured, reusable, `Clone` plan that holds the
  dimensionality, the `DistanceMetric`, and the backend's own `Config`. Build an
  index with `build`; reuse one builder for as many builds as you like.
  - `IndexBuilder::new(dim, metric)` — default config.
  - `IndexBuilder::with_config(dim, metric, config)` — the Tier-2 tuning entry.
  - `dim()`, `metric()`, `config()` accessors.
- **`build(dim, metric, items)`** — Tier-1 lazy path: construct a fresh index in
  one call from any `IntoIterator` of items, using the default config.
- **`build_into(index, items)`** — Tier-1 incremental path: bulk-insert into an
  index you already hold. Bound on the object-safe `IndexCore`, so it works on a
  concrete index *or* a `&mut dyn IndexCore` trait object.
- **`BuildItem`** — the `(VectorId, Arc<[f32]>, Option<Metadata>)` tuple the
  index already consumes. Building never reshapes or re-copies your data: the
  `Arc` you supply is the allocation the index stores.

The crate adds **no error type and no data type of its own**. Every fallible call
returns `iqdb_types::Result`, propagating the backend's errors unchanged, and the
crate has zero `unsafe`.

## How to use it

```rust
use std::sync::Arc;
use iqdb_build::{build, build_into, IndexBuilder};
use iqdb_types::{DistanceMetric, VectorId};

// One-call build (default config). `MyIndex: iqdb_index::Index`.
let mut index: MyIndex = build(3, DistanceMetric::Euclidean, vec![
    (VectorId::from(1u64), Arc::from([0.0_f32, 0.0, 0.0].as_slice()), None),
    (VectorId::from(2u64), Arc::from([1.0_f32, 0.0, 0.0].as_slice()), None),
])?;

// Append more vectors later without rebuilding.
let added = build_into(&mut index, more_items)?;

// Tuning the backend: use the builder with an explicit config.
let index: MyIndex = IndexBuilder::with_config(768, DistanceMetric::Cosine, my_config)
    .build(items)?;
```

## Breaking changes

This is a pre-1.0 minor release; the surface is purely additive over the 0.1.0
scaffold (which had no public API beyond `VERSION`). One internal change worth
noting:

- The vestigial `std` / `serde` feature split was removed. `iqdb-build` builds on
  the std-only `iqdb-index`, so there is no `no_std` build to gate; the crate now
  has **no feature flags**.

## Verification

```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features        # integration + property + doctests
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo bench --no-run             # criterion build-throughput baseline compiles
```

Tested across the CI matrix (Linux, macOS, Windows) on stable and the 1.87 MSRV.
The invariants are property-tested, not just exemplified: completeness (every
well-formed item lands exactly once), equivalence (`build` matches
construct-then-insert-one-at-a-time), additivity (`build_into` raises `len()` by
exactly the batch size), and duplicate rejection.

## What's next

- **v0.3.0 — rayon parallel construction + batching.** Shard the input across CPU
  cores and feed each backend through its vectorized `insert_batch` path, with
  criterion baselines on the hot path.
- **v0.4.0 — index merging (`Mergeable`) + progress reporting + feature freeze.**
  Combine independently built sub-indexes into one; optional progress callbacks
  for long-running builds.

## Installation

```toml
[dependencies]
iqdb-build = "0.2"
```

## Documentation

- [README](https://github.com/jamesgober/iqdb-build/blob/main/README.md)
- [API reference](https://github.com/jamesgober/iqdb-build/blob/main/docs/API.md)
- [ROADMAP](https://github.com/jamesgober/iqdb-build/blob/main/dev/ROADMAP.md)
- [Standards (REPS)](https://github.com/jamesgober/iqdb-build/blob/main/REPS.md)
- [CHANGELOG](https://github.com/jamesgober/iqdb-build/blob/main/CHANGELOG.md)

---

**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/iqdb-build/blob/main/CHANGELOG.md).
