Skip to content

feat(rust/sedona-raster): add ViewEntries view-spec module - #934

Merged
paleolimbot merged 2 commits into
apache:mainfrom
james-willis:jw/raster-view-entries
Jun 10, 2026
Merged

feat(rust/sedona-raster): add ViewEntries view-spec module#934
paleolimbot merged 2 commits into
apache:mainfrom
james-willis:jw/raster-view-entries

Conversation

@james-willis

@james-willis james-willis commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

This PR isolates just the machinery for the lazy view support. A subsequent PR will contain the integration(s) into the raster type.

This is spun out from #813

AI generated description

Adds view_entries.rs, the per-axis view-spec layer for N-D raster bands. No consumers are wired up yet — the reader/builder integration is the follow-up — so there is no behavior change.

ViewEntry

The per-axis spec (source_axis, start, step, steps), moved here from traits.rs and re-exported as crate::traits::ViewEntry so existing import paths are unchanged. step == 0 is broadcast, negative step is reverse iteration, and steps == 0 is an empty axis.

ViewEntries

A newtype over Vec<ViewEntry> that owns the view logic:

  • validate(source_shape) — the load-bearing check: view length matches source_shape, each source_axis is in range and the axes form a permutation of 0..ndim, steps >= 0, and the addressed extent start + (steps - 1) * step stays within [0, source_shape[axis]). Uses checked_* arithmetic so a pathological spec errors rather than wrapping.
  • visible_shape() — the visible extent (steps per axis); this is what a band reports as its shape().
  • is_identity(source_shape) — whether the view is the canonical no-op, so it can be stored as a NULL view row.
  • compose(next) — stacks a new view over an already-viewed band, translating next's axes (which index the visible axes) back onto the source axes. This is what lets views nest without materializing.
  • identity_for_shape, plus len / is_empty / as_slice / iter accessors.

view_entries! macro

A terse constructor taking start:stop half-open ranges per axis: view_entries![0:4, 1:5] yields source_axis = position, step = 1, steps = stop - start for each axis. Convenience for call sites and tests.

Scope

Pure spec logic — no I/O, no Arrow columns; the only allocation is the small Vec<ViewEntry> (ndim is a handful). Fully unit-tested in-module (validation rejections, composition, identity, visible-shape). It's the substrate the integration PR builds on.

Introduce the ViewEntries newtype over Vec<ViewEntry> with the view
machinery — validation, identity check, visible-shape derivation, and
composition — plus the view_entries! construction macro. Move ViewEntry
into the module and re-export it from traits so existing import paths
keep working. Pure, allocation-light spec logic with unit tests; no
behavior change to band construction or reads yet.
@github-actions
github-actions Bot requested a review from zhangfengcdt June 9, 2026 20:42
@james-willis
james-willis marked this pull request as ready for review June 9, 2026 21:04

@paleolimbot paleolimbot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I am still a tiny bit confused as to why source_axis is part of the view entry, since it seems there's a bit of work spent validating it only appears once. Can it be dropped and the index of the ViewEntry in the Vec be used instead? (Or if not, can a comment get added explaining why that can't happen?)

Comment thread rust/sedona-raster/src/traits.rs Outdated
Comment thread rust/sedona-raster/src/view_entries.rs
Comment thread rust/sedona-raster/src/view_entries.rs
@james-willis

Copy link
Copy Markdown
Contributor Author

I am still a tiny bit confused as to why source_axis is part of the view entry

One functionality of this views feature is to allow bands to be permuted, e.g. [x, y, z] -> [z, y, x]. The indices of the entries in ViewEntries defines the target band ordering. the values of source_axis defines the source band location.

The index cannot be used to define the source axis because it is used to define the target axis.

One example: GDAL-backed functions with band stacking require y then x are the last two dimensions. If the source raster does not have this behavior a permutation is neccessary.

@paleolimbot

Copy link
Copy Markdown
Member

Got it...this is also defining the permutation in addition to the view.

Address review: remove the pub-use re-export of ViewEntry from traits
(internal crates import from view_entries directly), and add a
try_new(inner, source_shape) that wraps and validates in one step.
@paleolimbot paleolimbot changed the title feat(raster): add ViewEntries view-spec module feat(rust/sedona-raster): add ViewEntries view-spec module Jun 10, 2026
@paleolimbot
paleolimbot merged commit f64ed45 into apache:main Jun 10, 2026
17 checks passed
@paleolimbot paleolimbot added this to the 0.4.0 milestone Jun 18, 2026
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