From cf9df40e7af97f7fdd50239a1a0eab5501302120 Mon Sep 17 00:00:00 2001 From: PB <37089506+pbower@users.noreply.github.com> Date: Tue, 7 Apr 2026 10:07:43 +1000 Subject: [PATCH] Document ArrayView --- src/structs/chunked/super_array.rs | 2 +- src/structs/views/array_view.rs | 16 ++++++++++++++-- src/structs/views/bitmask_view.rs | 5 +++++ .../views/collections/boolean_array_view.rs | 13 +++++++++++-- .../views/collections/numeric_array_view.rs | 4 ++-- .../views/collections/temporal_array_view.rs | 13 +++++++++++-- src/structs/views/collections/text_array_view.rs | 13 +++++++++++-- 7 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/structs/chunked/super_array.rs b/src/structs/chunked/super_array.rs index 6258e57..b72caa7 100644 --- a/src/structs/chunked/super_array.rs +++ b/src/structs/chunked/super_array.rs @@ -171,7 +171,7 @@ impl SuperArray { /// /// # Panics /// Panics if chunks have mismatched types or null_counts length doesn't match chunks length. - pub fn from_arrays_with_null_counts(chunks: Vec, null_counts: Vec) -> Self { + pub fn from_arrays_nc(chunks: Vec, null_counts: Vec) -> Self { assert_eq!( chunks.len(), null_counts.len(), diff --git a/src/structs/views/array_view.rs b/src/structs/views/array_view.rs index 1dd8d4a..ccd47ac 100644 --- a/src/structs/views/array_view.rs +++ b/src/structs/views/array_view.rs @@ -56,6 +56,9 @@ use crate::{Array, BitmaskV, FieldArray, MaskedArray, TextArray}; /// # ArrayView /// /// Logical, windowed view over an `Array`. +/// +/// ArrayView handles indexing offsets automatically so that the View behaves +/// like a regular array. /// /// ## Purpose /// This is used to return an indexable view over a subset of the array. @@ -74,9 +77,18 @@ use crate::{Array, BitmaskV, FieldArray, MaskedArray, TextArray}; /// - Use [`to_array`](Self::to_array) to materialise as an owned array. #[derive(Clone, PartialEq)] pub struct ArrayV { + /// The **outer array** that this view is derived from - we retain a reference to it. + /// Importantly, this is the ***full array*** - not the *view*, and thus should not be + /// accessed as though it were the view subset. pub array: Array, // contains Arc + /// The index offset from 0 that for where this view starts from the outer array pub offset: usize, + /// The length of the array view len: usize, + /// How many nulls are in the ArrayView + /// At construction, this is None, unless constructed via new_nc. When one uses '.null_count()', + /// the first time it will calculate it (quickly) using Bitmask popcount, and then from that + /// point onwards the null count is a cached value. null_count: OnceLock, } @@ -100,7 +112,7 @@ impl ArrayV { /// Construct a windowed view, supplying a precomputed null count. #[inline] - pub fn with_null_count(array: Array, offset: usize, len: usize, null_count: usize) -> Self { + pub fn new_nc(array: Array, offset: usize, len: usize, null_count: usize) -> Self { assert!( offset + len <= array.len(), "ArrayView: window out of bounds (offset + len = {}, array.len = {})", @@ -945,7 +957,7 @@ mod tests { arr.push(6); let array = Array::NumericArray(NumericArray::Int32(Arc::new(arr))); - let view = ArrayV::with_null_count(array, 0, 2, 99); + let view = ArrayV::new_nc(array, 0, 2, 99); // Should always report the supplied cached value assert_eq!(view.null_count(), 99); // Trying to set again should fail since it's already initialized diff --git a/src/structs/views/bitmask_view.rs b/src/structs/views/bitmask_view.rs index 8005af2..a4cd343 100644 --- a/src/structs/views/bitmask_view.rs +++ b/src/structs/views/bitmask_view.rs @@ -79,8 +79,13 @@ use crate::{Bitmask, BitmaskVT}; /// ``` #[derive(Clone, PartialEq)] pub struct BitmaskV { + /// The **outer bitmask** that this view is derived from - we retain a reference to it. + /// Importantly, this is the ***full bitmask*** - not the *view*, and thus should not be + /// accessed as though it were the view subset. pub bitmask: Arc, + /// The index offset from 0 that for where this view starts from the outer bitmask pub offset: usize, + /// The bitmask length len: usize, } diff --git a/src/structs/views/collections/boolean_array_view.rs b/src/structs/views/collections/boolean_array_view.rs index 082d176..ee0cf10 100644 --- a/src/structs/views/collections/boolean_array_view.rs +++ b/src/structs/views/collections/boolean_array_view.rs @@ -67,9 +67,18 @@ use crate::{Array, ArrayV, BitmaskV, BooleanArray, MaskedArray}; /// - Use [`to_boolean_array`](Self::to_boolean_array) to materialise the data. #[derive(Clone, PartialEq)] pub struct BooleanArrayV { + /// The **outer array** that this view is derived from - we retain a reference to it. + /// Importantly, this is the ***full array*** - not the *view*, and thus should not be + /// accessed as though it were the view subset. pub array: Arc>, + /// The index offset from 0 that for where this view starts from the outer array pub offset: usize, + /// The length of the array view len: usize, + /// How many nulls are in the BooleanArrayView + /// At construction, this is None, unless constructed via new_nc. When one uses '.null_count()', + /// the first time it will calculate it (quickly) using Bitmask popcount, and then from that + /// point onwards the null count is a cached value. null_count: OnceLock, } @@ -91,7 +100,7 @@ impl BooleanArrayV { } /// Creates a new `BooleanArrayView` with a precomputed null count. - pub fn with_null_count( + pub fn new_nc( array: Arc>, offset: usize, len: usize, @@ -374,7 +383,7 @@ mod tests { arr.push(false); let arc = Arc::new(arr); - let view = BooleanArrayV::with_null_count(arc, 0, 2, 99); + let view = BooleanArrayV::new_nc(arc, 0, 2, 99); assert_eq!(view.null_count(), 99); // Trying to set again should fail since it's already initialised assert!(view.set_null_count(101).is_err()); diff --git a/src/structs/views/collections/numeric_array_view.rs b/src/structs/views/collections/numeric_array_view.rs index b9a46a5..6cbf8b9 100644 --- a/src/structs/views/collections/numeric_array_view.rs +++ b/src/structs/views/collections/numeric_array_view.rs @@ -103,7 +103,7 @@ impl NumericArrayV { } /// Creates a new `NumericArrayView` with a precomputed null count. - pub fn with_null_count( + pub fn new_nc( array: NumericArray, offset: usize, len: usize, @@ -519,7 +519,7 @@ mod tests { arr.push(6); let numeric = NumericArray::Int32(Arc::new(arr)); - let view = NumericArrayV::with_null_count(numeric.clone(), 0, 2, 99); + let view = NumericArrayV::new_nc(numeric.clone(), 0, 2, 99); // Should always report the supplied cached value assert_eq!(view.null_count(), 99); // Trying to set again should fail since it's already initialised diff --git a/src/structs/views/collections/temporal_array_view.rs b/src/structs/views/collections/temporal_array_view.rs index 10c175c..e2ac562 100644 --- a/src/structs/views/collections/temporal_array_view.rs +++ b/src/structs/views/collections/temporal_array_view.rs @@ -78,9 +78,18 @@ use crate::{Array, ArrayV, BitmaskV, MaskedArray, TemporalArray}; /// - Use [`to_temporal_array`](Self::to_temporal_array) to materialise the window. #[derive(Clone, PartialEq)] pub struct TemporalArrayV { + /// The **outer array** that this view is derived from - we retain a reference to it. + /// Importantly, this is the ***full array*** - not the *view*, and thus should not be + /// accessed as though it were the view subset. pub array: TemporalArray, + /// The index offset from 0 that for where this view starts from the outer array pub offset: usize, + /// The length of the array view len: usize, + /// How many nulls are in the TemporalArrayView + /// At construction, this is None, unless constructed via new_nc. When one uses '.null_count()', + /// the first time it will calculate it (quickly) using Bitmask popcount, and then from that + /// point onwards the null count is a cached value. null_count: OnceLock, } @@ -102,7 +111,7 @@ impl TemporalArrayV { } /// Creates a new `TemporalArrayView` with a precomputed null count. - pub fn with_null_count( + pub fn new_nc( array: TemporalArray, offset: usize, len: usize, @@ -754,7 +763,7 @@ mod tests { fn test_temporal_array_view_with_supplied_null_count() { let arr = DatetimeArray::::from_slice(&[5, 6], None); let temporal = TemporalArray::Datetime64(Arc::new(arr)); - let view = TemporalArrayV::with_null_count(temporal, 0, 2, 99); + let view = TemporalArrayV::new_nc(temporal, 0, 2, 99); assert_eq!(view.null_count(), 99); // Trying to set again should fail since it\'s already initialized assert!(view.set_null_count(101).is_err()); diff --git a/src/structs/views/collections/text_array_view.rs b/src/structs/views/collections/text_array_view.rs index 4fc8651..b89d66a 100644 --- a/src/structs/views/collections/text_array_view.rs +++ b/src/structs/views/collections/text_array_view.rs @@ -73,9 +73,18 @@ use crate::{Array, ArrayV, BitmaskV, StringArray, TextArray}; /// - Use [`to_text_array`](Self::to_text_array) to materialise the data. #[derive(Clone, PartialEq)] pub struct TextArrayV { + /// The **outer array** that this view is derived from - we retain a reference to it. + /// Importantly, this is the ***full array*** - not the *view*, and thus should not be + /// accessed as though it were the view subset. pub array: TextArray, + /// The index offset from 0 that for where this view starts from the outer array pub offset: usize, + /// The length of the array view len: usize, + /// How many nulls are in the TextArrayView + /// At construction, this is None, unless constructed via new_nc. When one uses '.null_count()', + /// the first time it will calculate it (quickly) using Bitmask popcount, and then from that + /// point onwards the null count is a cached value. null_count: OnceLock, } @@ -97,7 +106,7 @@ impl TextArrayV { } /// Creates a new `TextArrayView` with a precomputed null count. - pub fn with_null_count(array: TextArray, offset: usize, len: usize, null_count: usize) -> Self { + pub fn new_nc(array: TextArray, offset: usize, len: usize, null_count: usize) -> Self { assert!( offset + len <= array.len(), "TextArrayView: window out of bounds (offset + len = {}, array.len = {})", @@ -412,7 +421,7 @@ mod tests { fn test_text_array_view_with_supplied_null_count() { let arr = StringArray::::from_slice(&["g", "h"]); let text = TextArray::String32(Arc::new(arr)); - let view = TextArrayV::with_null_count(text, 0, 2, 99); + let view = TextArrayV::new_nc(text, 0, 2, 99); assert_eq!(view.null_count(), 99); // Trying to set again should fail since it's already initialised assert!(view.set_null_count(101).is_err());