This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new aa9b9231c2 docs(arrow-data): Document how `ArrayData::offset` applies
to buffers, child_data and nulls (#10838)
aa9b9231c2 is described below
commit aa9b9231c29d9f9f9132eec2e1ba516728cc52a4
Author: Andrew Lamb <[email protected]>
AuthorDate: Wed Aug 26 17:35:59 2026 -0400
docs(arrow-data): Document how `ArrayData::offset` applies to buffers,
child_data and nulls (#10838)
# Which issue does this PR close?
- Part of #7595.
# Rationale for this change
The invariants governing `ArrayData::offset` are currently documented
only on the **private fields** of `ArrayData`, so they never appear in
rendered rustdoc.
- offset field
https://github.com/apache/arrow-rs/blob/7d9bdfd8a83eb66672826757c324e6fc73d20d53/arrow-data/src/data.rs#L215-L219
- child_data field
https://github.com/apache/arrow-rs/blob/7d9bdfd8a83eb66672826757c324e6fc73d20d53/arrow-data/src/data.rs#L235-L244
This was making it hard for me to reason about what a correct fix looks
like when offset-handling like #7595 / #7750 and #10835, where the
correct output of `ArrayData::slice` depends on these definitions
# What changes are included in this PR?
This PR surfaces those invariants on the public accessors so they are
visible in the docs and can be cited as the authority in code and
reviews.
# Are these changes tested?
Docs only; covered by CI doc builds.
# Are there any user-facing changes?
Documentation only — no behavior changes.
---
arrow-data/src/data.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 61 insertions(+), 2 deletions(-)
diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs
index 0df882dab5..7bf9520785 100644
--- a/arrow-data/src/data.rs
+++ b/arrow-data/src/data.rs
@@ -216,6 +216,8 @@ pub struct ArrayData {
///
/// The offset applies to [`Self::child_data`] and [`Self::buffers`]. It
/// does NOT apply to [`Self::nulls`].
+ ///
+ /// See [`Self::offset()`] for details and diagrams.
offset: usize,
/// The buffers that store the actual data for this array, as defined
@@ -241,13 +243,15 @@ pub struct ArrayData {
///
/// If the child element also has an offset then these offsets are
/// cumulative.
+ ///
+ /// See [`Self::child_data()`] and [`Self::offset()`] for details.
child_data: Vec<ArrayData>,
/// The null bitmap.
///
/// `None` indicates all values are non-null in this array.
///
- /// [`Self::offset]` does not apply to the null bitmap. While the
+ /// [`Self::offset()`] does not apply to the null bitmap. While the
/// BooleanBuffer may be sliced (have its own offset) internally, this
/// `NullBuffer` always represents exactly `len` elements.
nulls: Option<NullBuffer>,
@@ -432,6 +436,11 @@ impl ArrayData {
/// Returns a slice of children [`ArrayData`]. This will be non
/// empty for type such as lists and structs.
+ ///
+ /// Note: For nested types where the parent element `i` corresponds
directly
+ /// to child element `i` (such as structs), both the parent's offset and
+ /// each child's own offset apply when locating child values — see
+ /// [`Self::offset`] for details.
pub fn child_data(&self) -> &[ArrayData] {
&self.child_data[..]
}
@@ -471,7 +480,57 @@ impl ArrayData {
self.len == 0
}
- /// Returns the offset of this [`ArrayData`]
+ /// Returns the offset in elements of this [`ArrayData`]
+ ///
+ /// The offset applies to [`Self::buffers`] and [`Self::child_data`],
+ /// but does NOT apply to [`Self::nulls`], which always represents exactly
+ /// [`Self::len`] elements.
+ ///
+ /// # Offsets for Non-nested types
+ ///
+ /// For non-nested types, the offset skips leading elements in the buffers.
+ /// Logical element `i` is stored at physical position `offset + i`.
+ ///
+ /// For example, with `offset = 2` and `len = 3` the following array
+ /// represents elements `[C, D, E]`:
+ ///
+ /// ```text
+ /// offset: 2 len: 3
+ /// ◀───────────▶◀────────────────▶
+ /// ┌─────┬─────┬─────┬─────┬─────┬─────┐
+ /// values buffer │ A │ B │ C │ D │ E │ F │
+ /// └─────┴─────┴─────┴─────┴─────┴─────┘
+ /// physical index 0 1 2 3 4 5
+ /// logical index 0 1 2
+ /// ```
+ ///
+ /// # Offsets for Struct types
+ ///
+ /// For [struct]s, logical element `i` of the parent corresponds directly
to
+ /// element `i` of each child, with no indirection in between. Since a
+ /// struct has no buffers of its own, its offset applies to each child,
+ /// composing cumulatively with any child offset. Logical element `i` of
the
+ /// struct corresponds to element `offset + i` of each child.
+ ///
+ /// For example, a struct with `offset = 2` and `len = 3` whose children
+ /// `c1` and `c2` themselves each have an offset of `1` represents the
+ /// elements `{c1: D, c2: d}`, `{c1: E, c2: e}`, `{c1: F, c2: f}`:
+ ///
+ /// ```text
+ /// struct offset: 2 len: 3
+ /// ◀───────────▶◀────────────────▶
+ /// child offset: 1 ◀─────▶
+ /// ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
+ /// child c1 │ A │ B │ C │ D │ E │ F │ G │
+ /// ├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
+ /// child c2 │ a │ b │ c │ d │ e │ f │ g │
+ /// └─────┴─────┴─────┴─────┴─────┴─────┴─────┘
+ /// physical index 0 1 2 3 4 5 6
+ /// child index 0 1 2 3 4 5
+ /// struct index 0 1 2
+ /// ```
+ ///
+ /// [struct]:
https://arrow.apache.org/docs/format/Columnar.html#struct-layout
#[inline]
pub const fn offset(&self) -> usize {
self.offset