This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 91b2d7e66 Add ArrayAccessor trait, remove duplication in array
iterators (#1948) (#2133)
91b2d7e66 is described below
commit 91b2d7e66b066d54035774625b29ff226c755172
Author: Raphael Taylor-Davies <[email protected]>
AuthorDate: Fri Jul 22 15:20:49 2022 -0400
Add ArrayAccessor trait, remove duplication in array iterators (#1948)
(#2133)
* Add ArrayAccessor trait (#1948)
* Re-export ArrayAccessor
* Add docs
---
arrow/src/array/array.rs | 79 +++++++++
arrow/src/array/array_binary.rs | 15 ++
arrow/src/array/array_boolean.rs | 13 ++
arrow/src/array/array_list.rs | 27 ++-
arrow/src/array/array_primitive.rs | 13 ++
arrow/src/array/array_string.rs | 15 ++
arrow/src/array/equal_json.rs | 10 ++
arrow/src/array/iterator.rs | 331 +++----------------------------------
arrow/src/array/mod.rs | 1 +
9 files changed, 193 insertions(+), 311 deletions(-)
diff --git a/arrow/src/array/array.rs b/arrow/src/array/array.rs
index 3d8fdd70b..5c5231296 100644
--- a/arrow/src/array/array.rs
+++ b/arrow/src/array/array.rs
@@ -297,6 +297,85 @@ impl Array for ArrayRef {
}
}
+impl<'a, T: Array> Array for &'a T {
+ fn as_any(&self) -> &dyn Any {
+ T::as_any(self)
+ }
+
+ fn data(&self) -> &ArrayData {
+ T::data(self)
+ }
+
+ fn into_data(self) -> ArrayData {
+ self.data().clone()
+ }
+
+ fn data_ref(&self) -> &ArrayData {
+ T::data_ref(self)
+ }
+
+ fn data_type(&self) -> &DataType {
+ T::data_type(self)
+ }
+
+ fn slice(&self, offset: usize, length: usize) -> ArrayRef {
+ T::slice(self, offset, length)
+ }
+
+ fn len(&self) -> usize {
+ T::len(self)
+ }
+
+ fn is_empty(&self) -> bool {
+ T::is_empty(self)
+ }
+
+ fn offset(&self) -> usize {
+ T::offset(self)
+ }
+
+ fn is_null(&self, index: usize) -> bool {
+ T::is_null(self, index)
+ }
+
+ fn is_valid(&self, index: usize) -> bool {
+ T::is_valid(self, index)
+ }
+
+ fn null_count(&self) -> usize {
+ T::null_count(self)
+ }
+
+ fn get_buffer_memory_size(&self) -> usize {
+ T::get_buffer_memory_size(self)
+ }
+
+ fn get_array_memory_size(&self) -> usize {
+ T::get_array_memory_size(self)
+ }
+
+ fn to_raw(
+ &self,
+ ) -> Result<(*const ffi::FFI_ArrowArray, *const ffi::FFI_ArrowSchema)> {
+ T::to_raw(self)
+ }
+}
+
+/// A generic trait for accessing the values of an [`Array`]
+pub trait ArrayAccessor: Array {
+ type Item: Send + Sync;
+
+ /// Returns the element at index `i`
+ /// # Panics
+ /// Panics if the value is outside the bounds of the array
+ fn value(&self, index: usize) -> Self::Item;
+
+ /// Returns the element at index `i`
+ /// # Safety
+ /// Caller is responsible for ensuring that the index is within the bounds
of the array
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item;
+}
+
/// Constructs an array using the input `data`.
/// Returns a reference-counted `Array` instance.
pub fn make_array(data: ArrayData) -> ArrayRef {
diff --git a/arrow/src/array/array_binary.rs b/arrow/src/array/array_binary.rs
index d9cad1cce..b01696b03 100644
--- a/arrow/src/array/array_binary.rs
+++ b/arrow/src/array/array_binary.rs
@@ -23,6 +23,7 @@ use super::{
array::print_long_array, raw_pointer::RawPtrBox, Array, ArrayData,
FixedSizeListArray, GenericBinaryIter, GenericListArray, OffsetSizeTrait,
};
+use crate::array::array::ArrayAccessor;
pub use crate::array::DecimalIter;
use crate::buffer::Buffer;
use crate::error::{ArrowError, Result};
@@ -245,6 +246,20 @@ impl<OffsetSize: OffsetSizeTrait> Array for
GenericBinaryArray<OffsetSize> {
}
}
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor
+ for &'a GenericBinaryArray<OffsetSize>
+{
+ type Item = &'a [u8];
+
+ fn value(&self, index: usize) -> Self::Item {
+ GenericBinaryArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ GenericBinaryArray::value_unchecked(self, index)
+ }
+}
+
impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for
GenericBinaryArray<OffsetSize> {
fn from(data: ArrayData) -> Self {
assert_eq!(
diff --git a/arrow/src/array/array_boolean.rs b/arrow/src/array/array_boolean.rs
index 6e11ff8cb..5d1e20705 100644
--- a/arrow/src/array/array_boolean.rs
+++ b/arrow/src/array/array_boolean.rs
@@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.
+use crate::array::array::ArrayAccessor;
use std::borrow::Borrow;
use std::convert::From;
use std::iter::{FromIterator, IntoIterator};
@@ -157,6 +158,18 @@ impl Array for BooleanArray {
}
}
+impl<'a> ArrayAccessor for &'a BooleanArray {
+ type Item = bool;
+
+ fn value(&self, index: usize) -> Self::Item {
+ BooleanArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ BooleanArray::value_unchecked(self, index)
+ }
+}
+
impl From<Vec<bool>> for BooleanArray {
fn from(data: Vec<bool>) -> Self {
let mut mut_buf = MutableBuffer::new_null(data.len());
diff --git a/arrow/src/array/array_list.rs b/arrow/src/array/array_list.rs
index ac37754e9..22aa81ba7 100644
--- a/arrow/src/array/array_list.rs
+++ b/arrow/src/array/array_list.rs
@@ -24,6 +24,7 @@ use super::{
array::print_long_array, make_array, raw_pointer::RawPtrBox, Array,
ArrayData,
ArrayRef, BooleanBufferBuilder, GenericListArrayIter, PrimitiveArray,
};
+use crate::array::array::ArrayAccessor;
use crate::{
buffer::MutableBuffer,
datatypes::{ArrowNativeType, ArrowPrimitiveType, DataType, Field},
@@ -245,7 +246,7 @@ impl<OffsetSize: OffsetSizeTrait>
GenericListArray<OffsetSize> {
}
}
-impl<OffsetSize: 'static + OffsetSizeTrait> Array for
GenericListArray<OffsetSize> {
+impl<OffsetSize: OffsetSizeTrait> Array for GenericListArray<OffsetSize> {
fn as_any(&self) -> &dyn Any {
self
}
@@ -259,6 +260,18 @@ impl<OffsetSize: 'static + OffsetSizeTrait> Array for
GenericListArray<OffsetSiz
}
}
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor for &'a
GenericListArray<OffsetSize> {
+ type Item = ArrayRef;
+
+ fn value(&self, index: usize) -> Self::Item {
+ GenericListArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ GenericListArray::value(self, index)
+ }
+}
+
impl<OffsetSize: OffsetSizeTrait> fmt::Debug for GenericListArray<OffsetSize> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prefix = if OffsetSize::IS_LARGE { "Large" } else { "" };
@@ -466,6 +479,18 @@ impl Array for FixedSizeListArray {
}
}
+impl ArrayAccessor for FixedSizeListArray {
+ type Item = ArrayRef;
+
+ fn value(&self, index: usize) -> Self::Item {
+ FixedSizeListArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ FixedSizeListArray::value(self, index)
+ }
+}
+
impl fmt::Debug for FixedSizeListArray {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FixedSizeListArray<{}>\n[\n", self.value_length())?;
diff --git a/arrow/src/array/array_primitive.rs
b/arrow/src/array/array_primitive.rs
index 4ab8d4f46..eb731a2b2 100644
--- a/arrow/src/array/array_primitive.rs
+++ b/arrow/src/array/array_primitive.rs
@@ -33,6 +33,7 @@ use crate::{
util::trusted_len_unzip,
};
+use crate::array::array::ArrayAccessor;
use half::f16;
/// Array whose elements are of primitive types.
@@ -188,6 +189,18 @@ impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
}
}
+impl<'a, T: ArrowPrimitiveType> ArrayAccessor for &'a PrimitiveArray<T> {
+ type Item = T::Native;
+
+ fn value(&self, index: usize) -> Self::Item {
+ PrimitiveArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ PrimitiveArray::value_unchecked(self, index)
+ }
+}
+
fn as_datetime<T: ArrowPrimitiveType>(v: i64) -> Option<NaiveDateTime> {
match T::DATA_TYPE {
DataType::Date32 => Some(temporal_conversions::date32_to_datetime(v as
i32)),
diff --git a/arrow/src/array/array_string.rs b/arrow/src/array/array_string.rs
index 85cb346a7..df858d858 100644
--- a/arrow/src/array/array_string.rs
+++ b/arrow/src/array/array_string.rs
@@ -23,6 +23,7 @@ use super::{
array::print_long_array, raw_pointer::RawPtrBox, Array, ArrayData,
GenericListArray,
GenericStringIter, OffsetSizeTrait,
};
+use crate::array::array::ArrayAccessor;
use crate::buffer::Buffer;
use crate::util::bit_util;
use crate::{buffer::MutableBuffer, datatypes::DataType};
@@ -298,6 +299,20 @@ impl<OffsetSize: OffsetSizeTrait> Array for
GenericStringArray<OffsetSize> {
}
}
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor
+ for &'a GenericStringArray<OffsetSize>
+{
+ type Item = &'a str;
+
+ fn value(&self, index: usize) -> Self::Item {
+ GenericStringArray::value(self, index)
+ }
+
+ unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+ GenericStringArray::value_unchecked(self, index)
+ }
+}
+
impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for
GenericStringArray<OffsetSize> {
fn from(data: ArrayData) -> Self {
assert_eq!(
diff --git a/arrow/src/array/equal_json.rs b/arrow/src/array/equal_json.rs
index 30d9c8f84..e7d14aae8 100644
--- a/arrow/src/array/equal_json.rs
+++ b/arrow/src/array/equal_json.rs
@@ -37,6 +37,16 @@ pub trait JsonEqual {
}
}
+impl<'a, T: JsonEqual> JsonEqual for &'a T {
+ fn equals_json(&self, json: &[&Value]) -> bool {
+ T::equals_json(self, json)
+ }
+
+ fn equals_json_values(&self, json: &[Value]) -> bool {
+ T::equals_json_values(self, json)
+ }
+}
+
/// Implement array equals for numeric type
impl<T: ArrowPrimitiveType> JsonEqual for PrimitiveArray<T> {
fn equals_json(&self, json: &[&Value]) -> bool {
diff --git a/arrow/src/array/iterator.rs b/arrow/src/array/iterator.rs
index 8e45de286..a4853d7d7 100644
--- a/arrow/src/array/iterator.rs
+++ b/arrow/src/array/iterator.rs
@@ -15,36 +15,37 @@
// specific language governing permissions and limitations
// under the License.
+use crate::array::array::ArrayAccessor;
use crate::array::BasicDecimalArray;
-use crate::datatypes::ArrowPrimitiveType;
use super::{
- Array, ArrayRef, BooleanArray, Decimal128Array, GenericBinaryArray,
GenericListArray,
- GenericStringArray, OffsetSizeTrait, PrimitiveArray,
+ Array, BooleanArray, Decimal128Array, GenericBinaryArray, GenericListArray,
+ GenericStringArray, PrimitiveArray,
};
-/// an iterator that returns Some(T) or None, that can be used on any
PrimitiveArray
+/// an iterator that returns Some(T) or None, that can be used on any
[`ArrayAccessor`]
// Note: This implementation is based on std's [Vec]s' [IntoIter].
#[derive(Debug)]
-pub struct PrimitiveIter<'a, T: ArrowPrimitiveType> {
- array: &'a PrimitiveArray<T>,
+pub struct ArrayIter<T: ArrayAccessor> {
+ array: T,
current: usize,
current_end: usize,
}
-impl<'a, T: ArrowPrimitiveType> PrimitiveIter<'a, T> {
+impl<T: ArrayAccessor> ArrayIter<T> {
/// create a new iterator
- pub fn new(array: &'a PrimitiveArray<T>) -> Self {
- PrimitiveIter::<T> {
+ pub fn new(array: T) -> Self {
+ let len = array.len();
+ ArrayIter {
array,
current: 0,
- current_end: array.len(),
+ current_end: len,
}
}
}
-impl<'a, T: ArrowPrimitiveType> std::iter::Iterator for PrimitiveIter<'a, T> {
- type Item = Option<T::Native>;
+impl<T: ArrayAccessor> Iterator for ArrayIter<T> {
+ type Item = Option<T::Item>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
@@ -73,7 +74,7 @@ impl<'a, T: ArrowPrimitiveType> std::iter::Iterator for
PrimitiveIter<'a, T> {
}
}
-impl<'a, T: ArrowPrimitiveType> std::iter::DoubleEndedIterator for
PrimitiveIter<'a, T> {
+impl<T: ArrayAccessor> DoubleEndedIterator for ArrayIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.current_end == self.current {
None
@@ -94,304 +95,14 @@ impl<'a, T: ArrowPrimitiveType>
std::iter::DoubleEndedIterator for PrimitiveIter
}
/// all arrays have known size.
-impl<'a, T: ArrowPrimitiveType> std::iter::ExactSizeIterator for
PrimitiveIter<'a, T> {}
-
-/// an iterator that returns Some(bool) or None.
-// Note: This implementation is based on std's [Vec]s' [IntoIter].
-#[derive(Debug)]
-pub struct BooleanIter<'a> {
- array: &'a BooleanArray,
- current: usize,
- current_end: usize,
-}
-
-impl<'a> BooleanIter<'a> {
- /// create a new iterator
- pub fn new(array: &'a BooleanArray) -> Self {
- BooleanIter {
- array,
- current: 0,
- current_end: array.len(),
- }
- }
-}
-
-impl<'a> std::iter::Iterator for BooleanIter<'a> {
- type Item = Option<bool>;
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.current == self.current_end {
- None
- } else if self.array.is_null(self.current) {
- self.current += 1;
- Some(None)
- } else {
- let old = self.current;
- self.current += 1;
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(Some(self.array.value_unchecked(old))) }
- }
- }
+impl<T: ArrayAccessor> ExactSizeIterator for ArrayIter<T> {}
- fn size_hint(&self) -> (usize, Option<usize>) {
- (
- self.array.len() - self.current,
- Some(self.array.len() - self.current),
- )
- }
-}
-
-impl<'a> std::iter::DoubleEndedIterator for BooleanIter<'a> {
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.current_end == self.current {
- None
- } else {
- self.current_end -= 1;
- Some(if self.array.is_null(self.current_end) {
- None
- } else {
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized
with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(self.array.value_unchecked(self.current_end)) }
- })
- }
- }
-}
-
-/// all arrays have known size.
-impl<'a> std::iter::ExactSizeIterator for BooleanIter<'a> {}
-
-/// an iterator that returns `Some(&str)` or `None`, for string arrays
-#[derive(Debug)]
-pub struct GenericStringIter<'a, T>
-where
- T: OffsetSizeTrait,
-{
- array: &'a GenericStringArray<T>,
- current: usize,
- current_end: usize,
-}
-
-impl<'a, T: OffsetSizeTrait> GenericStringIter<'a, T> {
- /// create a new iterator
- pub fn new(array: &'a GenericStringArray<T>) -> Self {
- GenericStringIter::<T> {
- array,
- current: 0,
- current_end: array.len(),
- }
- }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::Iterator for GenericStringIter<'a, T> {
- type Item = Option<&'a str>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let i = self.current;
- if i >= self.current_end {
- None
- } else if self.array.is_null(i) {
- self.current += 1;
- Some(None)
- } else {
- self.current += 1;
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(Some(self.array.value_unchecked(i))) }
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (
- self.current_end - self.current,
- Some(self.current_end - self.current),
- )
- }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::DoubleEndedIterator for
GenericStringIter<'a, T> {
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.current_end == self.current {
- None
- } else {
- self.current_end -= 1;
- Some(if self.array.is_null(self.current_end) {
- None
- } else {
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized
with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(self.array.value_unchecked(self.current_end)) }
- })
- }
- }
-}
-
-/// all arrays have known size.
-impl<'a, T: OffsetSizeTrait> std::iter::ExactSizeIterator for
GenericStringIter<'a, T> {}
-
-/// an iterator that returns `Some(&[u8])` or `None`, for binary arrays
-#[derive(Debug)]
-pub struct GenericBinaryIter<'a, T>
-where
- T: OffsetSizeTrait,
-{
- array: &'a GenericBinaryArray<T>,
- current: usize,
- current_end: usize,
-}
-
-impl<'a, T: OffsetSizeTrait> GenericBinaryIter<'a, T> {
- /// create a new iterator
- pub fn new(array: &'a GenericBinaryArray<T>) -> Self {
- GenericBinaryIter::<T> {
- array,
- current: 0,
- current_end: array.len(),
- }
- }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::Iterator for GenericBinaryIter<'a, T> {
- type Item = Option<&'a [u8]>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let i = self.current;
- if i >= self.current_end {
- None
- } else if self.array.is_null(i) {
- self.current += 1;
- Some(None)
- } else {
- self.current += 1;
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(Some(self.array.value_unchecked(i))) }
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (
- self.current_end - self.current,
- Some(self.current_end - self.current),
- )
- }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::DoubleEndedIterator for
GenericBinaryIter<'a, T> {
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.current_end == self.current {
- None
- } else {
- self.current_end -= 1;
- Some(if self.array.is_null(self.current_end) {
- None
- } else {
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized
with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(self.array.value_unchecked(self.current_end)) }
- })
- }
- }
-}
-
-/// all arrays have known size.
-impl<'a, T: OffsetSizeTrait> std::iter::ExactSizeIterator for
GenericBinaryIter<'a, T> {}
-
-#[derive(Debug)]
-pub struct GenericListArrayIter<'a, S>
-where
- S: OffsetSizeTrait,
-{
- array: &'a GenericListArray<S>,
- current: usize,
- current_end: usize,
-}
-
-impl<'a, S: OffsetSizeTrait> GenericListArrayIter<'a, S> {
- pub fn new(array: &'a GenericListArray<S>) -> Self {
- GenericListArrayIter::<S> {
- array,
- current: 0,
- current_end: array.len(),
- }
- }
-}
-
-impl<'a, S: OffsetSizeTrait> std::iter::Iterator for GenericListArrayIter<'a,
S> {
- type Item = Option<ArrayRef>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let i = self.current;
- if i >= self.current_end {
- None
- } else if self.array.is_null(i) {
- self.current += 1;
- Some(None)
- } else {
- self.current += 1;
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(Some(self.array.value_unchecked(i))) }
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (
- self.current_end - self.current,
- Some(self.current_end - self.current),
- )
- }
-}
-
-impl<'a, S: OffsetSizeTrait> std::iter::DoubleEndedIterator
- for GenericListArrayIter<'a, S>
-{
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.current_end == self.current {
- None
- } else {
- self.current_end -= 1;
- Some(if self.array.is_null(self.current_end) {
- None
- } else {
- // Safety:
- // we just checked bounds in `self.current_end == self.current`
- // this is safe on the premise that this struct is initialized
with
- // current = array.len()
- // and that current_end is ever only decremented
- unsafe { Some(self.array.value_unchecked(self.current_end)) }
- })
- }
- }
-}
-
-/// all arrays have known size.
-impl<'a, S: OffsetSizeTrait> std::iter::ExactSizeIterator
- for GenericListArrayIter<'a, S>
-{
-}
+/// an iterator that returns Some(T) or None, that can be used on any
PrimitiveArray
+pub type PrimitiveIter<'a, T> = ArrayIter<&'a PrimitiveArray<T>>;
+pub type BooleanIter<'a> = ArrayIter<&'a BooleanArray>;
+pub type GenericStringIter<'a, T> = ArrayIter<&'a GenericStringArray<T>>;
+pub type GenericBinaryIter<'a, T> = ArrayIter<&'a GenericBinaryArray<T>>;
+pub type GenericListArrayIter<'a, O> = ArrayIter<&'a GenericListArray<O>>;
/// an iterator that returns `Some(i128)` or `None`, that can be used on a
/// [`Decimal128Array`]
diff --git a/arrow/src/array/mod.rs b/arrow/src/array/mod.rs
index d805710cc..8acc33c7b 100644
--- a/arrow/src/array/mod.rs
+++ b/arrow/src/array/mod.rs
@@ -186,6 +186,7 @@ use crate::datatypes::*;
// --------------------- Array & ArrayData ---------------------
pub use self::array::Array;
+pub use self::array::ArrayAccessor;
pub use self::array::ArrayRef;
pub(crate) use self::data::layout;
pub use self::data::ArrayData;