# iqdb-flat v0.4.0 — Feature-complete

**The index is built.** v0.1.0 was the scaffold; v0.4.0 lands the whole flat
index onto it and wires it to the stable (`1.0`) iQDB spine. Exact search,
top-`k`, the `Index` trait, an optional parallel scan, and metadata
pre-filtering are all implemented and tested. The feature set is now complete;
what remains before `1.0` is API finalisation, polish, and final benchmarks.

## What is iqdb-flat?

The brute-force exact nearest-neighbour layer of the iQDB vector database. It
scans every stored vector on every query, computes the true distance, and
returns the top-`k` — always correct, by construction. That makes it two things
at once: a real index for small corpora (under ~10k vectors, where graph or
partition overhead is not justified) and the **recall ground truth** every
approximate index (HNSW, IVF) is measured against. It is the first and simplest
implementer of the `iqdb-index` `Index` trait, so it also validates that trait's
design.

## What's in 0.4.0

### The index

- **`FlatIndex`** implementing `iqdb_index::IndexCore` + `Index` — insert,
  delete, batch insert, single and batch search, `flush`, and `stats`.
- **`FlatConfig`** — a unit configuration type; the flat index has nothing to
  tune, but the seam exists for future knobs without an API break.
- **Exact top-`k`** via a bounded max-heap of size `k` keyed by
  `(distance, insertion-sequence)` — `O(n log k)`, NaN-safe through
  `f32::total_cmp`.

### Correctness guarantees

- **One ordering invariant.** `Hit.distance` is *smaller-is-nearer* for all five
  metrics; `DotProduct` (a similarity) is negated at the boundary so it sorts the
  same way as the rest.
- **Stable, deterministic ties.** Equal-distance hits rank by insertion order.
  That holds across feature flags and across delete-then-reinsert sequences: each
  row carries a monotonic stamp, and a re-inserted id gets a fresh, higher stamp,
  so it moves to the end of the tie.

### Performance

- **Amortized `O(1)` insert/delete** — a `HashMap` id→position map plus
  `swap_remove`, independent of corpus size (a 50k insert/delete/reinsert churn
  test guards against regression to `O(n²)`).
- **Zero-copy insert** — the caller's `Arc<[f32]>` is stored verbatim; no payload
  copy, so a consumer can share one allocation between the index and its own
  record store.
- **No-filter search allocates a fixed number of buffers** regardless of `n`
  (locked in by a global-allocator counting test).
- **Optional `parallel` feature** — a rayon chunked scan proven byte-identical to
  the sequential baseline; small corpora short-circuit to sequential.

### Metadata pre-filtering

- `SearchParams::filter` is evaluated through `iqdb-filter` **before** distance
  computation, so a selective filter skips distance work proportionally — and
  every iQDB index filters by one shared definition.

## Dependencies

Wired to the stable iQDB spine — all `1.0`:

```toml
iqdb-types    = "1.0.0"
iqdb-distance = "1.0.0"
iqdb-index    = "1.0.0"
iqdb-filter   = "1.0.0"
```

`parallel` additionally pulls `rayon`. There is no other dependency.

## Breaking changes

**None** in the API sense — v0.1.0 exposed no domain types. This release adds the
entire surface for the first time.

## Verification

Clean across the CI matrix (Linux, macOS, Windows) on stable and the 1.87 MSRV,
with default features and `--all-features`:

```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
```

Zero `unsafe` (`#![forbid(unsafe_code)]`); no `unwrap`/`expect`/`todo!`/`dbg!` in
shipping code. Correctness is pinned by property tests and an independent
differential oracle for all five metrics; the parallel path is proven equal to
the sequential one.

## What's next

- **v0.5.0 — large-scan correctness + API freeze.** Lock the public surface
  (recorded in `dev/ROADMAP.md`); `cargo audit` + `cargo deny` clean.
- **0.6.x → 0.9.x — alpha/beta/RC.** Integration against real approximate-index
  consumers (as the recall oracle), broader testing, final benchmarks, doc polish.
- **A contiguous row-major storage layout** is tracked as a post-0.4 internal
  optimisation (see the ROADMAP note); it does not change the public API.

## Installation

```toml
[dependencies]
iqdb-flat = "0.4"
```

## Documentation

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

---

**Full diff:** [`v0.1.0...v0.4.0`](https://github.com/jamesgober/iqdb-flat/compare/v0.1.0...v0.4.0).
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/iqdb-flat/blob/main/CHANGELOG.md).
