You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2022/07/22 16:54:17 UTC

[GitHub] [arrow-rs] viirya commented on a diff in pull request #2133: Add ArrayAccessor trait, remove duplication in array iterators (#1948)

viirya commented on code in PR #2133:
URL: https://github.com/apache/arrow-rs/pull/2133#discussion_r927835847


##########
arrow/src/array/iterator.rs:
##########
@@ -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>>;

Review Comment:
   👍 Nice



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org