Expand description
Columnar entity index — a compact, binary-searched alternative to the
EntityIndex FxHashMap<u32, (usize, usize)>.
§Why
The streaming pre-pass hands every wasm worker (N geometry workers plus the
prepass and parser workers) the same pre-scanned entity index as three
parallel u32 columns
via setEntityIndex. Each worker used to materialize a private
FxHashMap<u32, (usize, usize)> from those columns. hashbrown rounds the
bucket count up to the next power of two, so for a 19.1 M-entity model it
allocates 2^25 buckets × ~13 B ≈ 436 MB per worker, rebuilt in every
realm. Three sorted Vec<u32> columns for the same model are
3 × 19.1 M × 4 B ≈ 229 MB — no power-of-two rounding, no per-bucket control
byte, no (usize, usize) widening. The lookup becomes a binary_search
(≈24 probes at 19 M rows) instead of an O(1) hash probe; see the PR for the
measured wall-time delta on the full geometry pipeline.
§u32 offsets
starts/lengths are u32, which is only sound while the source file is
< 4 GiB. WASM ingestion (setEntityIndex and cached_entity_index) already
lives in that linear address space and delivers &[u32] columns. The native
processor also uses this representation for large sources with sparse ids,
after checking their byte length fits u32; dense ids may use
crate::DenseEntityIndex. Wider native sources keep the usize-carrying
EntityIndex hashmap.
§Duplicate express ids
crate::build_entity_index inserts scanned spans into an FxHashMap in
file order, so a repeated express id resolves to its last occurrence in
the file (HashMap::insert overwrites). Express ids are unique per the STEP
spec and duplicates essentially never occur, but this type replicates the
last-in-file-order-wins behaviour deliberately (see from_unsorted and the
duplicate_id_last_wins test) so a malformed file cannot diverge between the
hashmap and columnar paths.
Structs§
- Column
Length Mismatch - The three columns handed to
ColumnarEntityIndex::from_columnsorColumnarEntityIndex::from_owned_columnswere not all the same length. A caller-facing error, not an empty index: an empty index is also what an empty file produces, so folding the two together hid a malformed payload. - Columnar
Entity Index - Compact, sorted, binary-searched entity index. Columns are kept sorted by
ids(strictly ascending, unique) soSelf::lookupcanbinary_search.