1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//! Secondary indexes (L6) — index B+trees layered over the M4 B+tree.
//!
//! M7 adds *secondary indexes*: per-collection B+trees keyed by an
//! order-preserving encoding of one or more document fields, valued
//! by the document's [`Id`](crate::Id). See `docs/format.md`
//! § Indexes for the authoritative on-disk layout.
//!
//! Each declared index lives in its own B+tree (M4 — no new on-disk
//! page types). The index's root page-id is persisted inside the
//! owning [`CollectionDescriptor`](crate::catalog::CollectionDescriptor)
//! as an [`IndexDescriptor`](crate::catalog::IndexDescriptor) entry
//! (M5 reserved the field; M7 fills it).
//!
//! # Module split
//!
//! - [`spec`] — runtime declaration shapes: [`IndexKind`],
//! [`IndexSpec`], constructors. The descriptor on-disk shape lives
//! in [`crate::catalog`] because the catalog owns the wire row.
//! - [`key`] — order-preserving byte encoding for `Dynamic` values
//! plus the composite envelope. The encoding contract is documented
//! in `docs/format.md` § Index key encoding.
//!
//! # Power-of-ten posture
//!
//! - **Rule 1.** No recursion: the encoder walks the input
//! `&[Dynamic]` with a single bounded `for` loop.
//! - **Rule 2.** Per-encode loops are bounded by the input slice
//! length, which the caller has already validated against
//! `IndexSpec::key_paths.len()`.
//! - **Rule 5.** Field count is checked against `IndexSpec`'s
//! `key_paths` at the encode-time runtime boundary; type-level
//! invariants (kind enum, non-empty `key_paths` for composite,
//! single-field for `Each`) sit on the constructors.
//! - **Rule 7.** No `unwrap` / `expect` on the production path. The
//! encoder returns `Err(Error::Codec)` on `String` fields that
//! contain an embedded `0x00` (the terminator would split the
//! key — see `docs/format.md`).
//! - **Rule 9.** All dispatch is static — `IndexKind` is an enum
//! matched at every call site; no `dyn`, no macro generation.
pub use crate;
pub use crate;
pub use crate;