## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-array/src/trusted_len.rs

    Line
    Count
    Source
    1
    // Licensed to the Apache Software Foundation (ASF) under one
    2
    // or more contributor license agreements.  See the NOTICE file
    3
    // distributed with this work for additional information
    4
    // regarding copyright ownership.  The ASF licenses this file
    5
    // to you under the Apache License, Version 2.0 (the
    6
    // "License"); you may not use this file except in compliance
    7
    // with the License.  You may obtain a copy of the License at
    8
    //
    9
    //   http://www.apache.org/licenses/LICENSE-2.0
    10
    //
    11
    // Unless required by applicable law or agreed to in writing,
    12
    // software distributed under the License is distributed on an
    13
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14
    // KIND, either express or implied.  See the License for the
    15
    // specific language governing permissions and limitations
    16
    // under the License.
    17
    18
    use arrow_buffer::{bit_util, ArrowNativeType, Buffer, MutableBuffer};
    19
    20
    /// Creates two [`Buffer`]s from an iterator of `Option`.
    21
    /// The first buffer corresponds to a bitmap buffer, the second one
    22
    /// corresponds to a values buffer.
    23
    /// # Safety
    24
    /// The caller must ensure that `iterator` is `TrustedLen`.
    25
    #[inline]
    26
    0
    pub(crate) unsafe fn trusted_len_unzip<I, P, T>(iterator: I) -> (Buffer, Buffer)
    27
    0
    where
    28
    0
        T: ArrowNativeType,
    29
    0
        P: std::borrow::Borrow<Option<T>>,
    30
    0
        I: Iterator<Item = P>,
    31
    {
    32
    0
        let (_, upper) = iterator.size_hint();
    33
    0
        let upper = upper.expect("trusted_len_unzip requires an upper limit");
    34
    0
        let len = upper * std::mem::size_of::<T>();
    35
    36
    0
        let mut null = MutableBuffer::from_len_zeroed(upper.saturating_add(7) / 8);
    37
    0
        let mut buffer = MutableBuffer::new(len);
    38
    39
    0
        let dst_null = null.as_mut_ptr();
    40
    0
        let mut dst = buffer.as_mut_ptr() as *mut T;
    41
    0
        for (i, item) in iterator.enumerate() {
    42
    0
            let item = item.borrow();
    43
    0
            if let Some(item) = item {
    44
    0
                std::ptr::write(dst, *item);
    45
    0
                bit_util::set_bit_raw(dst_null, i);
    46
    0
            } else {
    47
    0
                std::ptr::write(dst, T::default());
    48
    0
            }
    49
    0
            dst = dst.add(1);
    50
        }
    51
    0
        assert_eq!(
    52
    0
            dst.offset_from(buffer.as_ptr() as *mut T) as usize,
    53
            upper,
    54
    0
            "Trusted iterator length was not accurately reported"
    55
        );
    56
    0
        buffer.set_len(len);
    57
    0
        (null.into(), buffer.into())
    58
    0
    }
    59
    60
    #[cfg(test)]
    61
    mod tests {
    62
        use super::*;
    63
    64
        #[test]
    65
        fn trusted_len_unzip_good() {
    66
            let vec = [Some(1u32), None];
    67
            let (null, buffer) = unsafe { trusted_len_unzip(vec.iter()) };
    68
            assert_eq!(null.as_slice(), &[0b00000001]);
    69
            assert_eq!(buffer.as_slice(), &[1u8, 0, 0, 0, 0, 0, 0, 0]);
    70
        }
    71
    72
        #[test]
    73
        #[should_panic(expected = "trusted_len_unzip requires an upper limit")]
    74
        fn trusted_len_unzip_panic() {
    75
            let iter = std::iter::repeat(Some(4i32));
    76
            unsafe { trusted_len_unzip(iter) };
    77
        }
    78
    }