Skip to content

Make StructArray use the array_slots macro accessors - #9006

Draft
joseph-isaacs wants to merge 2 commits into
developfrom
claude/array-slots-perf-fixes
Draft

Make StructArray use the array_slots macro accessors#9006
joseph-isaacs wants to merge 2 commits into
developfrom
claude/array-slots-perf-fixes

Conversation

@joseph-isaacs

Copy link
Copy Markdown
Contributor

Rationale for this change

Follow-up to #8950 (variadic #[array_slots], now merged). After that PR, StructSlots was only used for its two slot-index constants — the generated view, ext trait, and conversions were dead code. Union already subtypes its generated ext trait; Struct should too, so the macro is the single source of truth for struct slot access.

What changes are included in this PR?

  • StructArrayExt now extends the generated StructArraySlotsExt supertrait (matching UnionArrayExt).
  • Slot access is routed through the generated accessors instead of hand-written raw-slot indexing:
    • struct_validity() uses the generated validity() accessor.
    • iter_unmasked_fields() / unmasked_fields() / unmasked_field() use the generated fields() SlotSlice (a Copy, zero-copy borrow) rather than slots()[FIELDS_OFFSET + i] + hand-written vortex_expect.
  • Exports StructArraySlotsExt for parity with UnionArraySlotsExt.

What APIs are changed? Are there any user-facing changes?

No signature changes. StructArraySlotsExt is newly exported. Read-path cost is unchanged — SlotSlice is a borrow, so this only removes duplicated hand-rolled slot indexing.

Verification

  • cargo test -p vortex-array --lib -- arrays::struct_ arrays::union arrays::masked — passed
  • cargo clippy --all-targets -p vortex-array — clean
  • cargo +nightly fmt -p vortex-array — clean

Could not run a full cargo build --workspace in this environment (protoc missing, DuckDB download blocked by network policy, limited disk); crates touching the changed API were checked individually.

🤖 Generated with Claude Code


Generated by Claude Code

Previously StructSlots was only used for its two index constants; the
generated view, ext trait, and conversions were dead. Make StructArrayExt
a subtrait of the generated StructArraySlotsExt and route slot access
through the generated accessors, matching UnionArrayExt:

- struct_validity() uses the generated `validity()` slot accessor.
- iter_unmasked_fields() / unmasked_fields() / unmasked_field() use the
  generated `fields()` SlotSlice (zero-copy borrow) instead of indexing
  raw slots with hand-written vortex_expect.
- Export StructArraySlotsExt for parity with UnionArraySlotsExt.

Read paths are unchanged in cost (SlotSlice is a Copy borrow); this only
removes the duplicated hand-rolled slot indexing.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BF3K2eZTEnCsqMsN3wGtc
- SlotSlice now implements IntoIterator (via a named SlotSliceIter that
  is ExactSizeIterator + DoubleEndedIterator), so it can be used directly
  in for-loops and passed anywhere an iterator is expected without
  calling .iter().
- Route StructArray field callers through iter_unmasked_fields() instead
  of the owned-Vec unmasked_fields():
  - Pure-iteration sites (is_constant, listview conversion, tui browse)
    no longer allocate a Vec or clone every field just to read them.
  - Construction sites (struct mask reduce, push_validity_into_children,
    masked struct execute, sparse canonicalization) now pass
    iter_unmasked_fields().cloned() straight into the
    impl IntoIterator<Item = ArrayRef> constructors, so the single
    collect happens inside the constructor instead of building an
    intermediate Vec first (saves one allocation + N moves per call).
- Widen iter_unmasked_fields() to impl ExactSizeIterator (its backing
  SlotSliceIter already is), enabling len()-based capacity hints.

unmasked_fields() (owned Vec) is kept for the remaining indexed/test
callers.

Verification:
- cargo test -p vortex-array --lib -- arrays::struct_ arrays::masked aggregate_fn::fns::is_constant arrays::listview patched::array::tests (219 passed)
- cargo clippy --all-targets -p vortex-array
- cargo check -p vortex-tui -p vortex-sparse -p vortex-layout -p vortex-row -p vortex-compressor
- cargo +nightly fmt

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BF3K2eZTEnCsqMsN3wGtc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants