Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
try_new_unchecked for ListArray
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao committed Mar 1, 2022
1 parent 71b3ba5 commit bf4f4df
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
81 changes: 80 additions & 1 deletion src/array/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ use crate::{
error::ArrowError,
};

use super::{new_empty_array, specification::try_check_offsets, Array, Offset};
use super::{
new_empty_array,
specification::{try_check_offsets, try_check_offsets_bounds},
Array, Offset,
};

mod ffi;
pub(super) mod fmt;
Expand Down Expand Up @@ -35,6 +39,8 @@ impl<O: Offset> ListArray<O> {
/// * the validity's length is not equal to `offsets.len() - 1`.
/// * The `data_type`'s [`crate::datatypes::PhysicalType`] is not equal to either [`crate::datatypes::PhysicalType::List`] or [`crate::datatypes::PhysicalType::LargeList`].
/// * The `data_type`'s inner field's data type is not equal to `values.data_type`.
/// # Implementation
/// This function is `O(N)` - checking monotinicity is `O(N)`
pub fn try_new(
data_type: DataType,
offsets: Buffer<O>,
Expand Down Expand Up @@ -77,6 +83,8 @@ impl<O: Offset> ListArray<O> {
/// * the validity's length is not equal to `offsets.len() - 1`.
/// * The `data_type`'s [`crate::datatypes::PhysicalType`] is not equal to either [`crate::datatypes::PhysicalType::List`] or [`crate::datatypes::PhysicalType::LargeList`].
/// * The `data_type`'s inner field's data type is not equal to `values.data_type`.
/// # Implementation
/// This function is `O(N)` - checking monotinicity is `O(N)`
pub fn new(
data_type: DataType,
offsets: Buffer<O>,
Expand Down Expand Up @@ -115,6 +123,77 @@ impl<O: Offset> ListArray<O> {
}
}

// unsafe construtors
impl<O: Offset> ListArray<O> {
/// Creates a new [`ListArray`].
///
/// # Errors
/// This function returns an error iff:
/// * The last offset is not equal to the values' length.
/// * the validity's length is not equal to `offsets.len() - 1`.
/// * The `data_type`'s [`crate::datatypes::PhysicalType`] is not equal to either [`crate::datatypes::PhysicalType::List`] or [`crate::datatypes::PhysicalType::LargeList`].
/// * The `data_type`'s inner field's data type is not equal to `values.data_type`.
/// # Safety
/// This function is unsafe iff:
/// * the offsets are not monotonically increasing
/// # Implementation
/// This function is `O(1)`
pub unsafe fn try_new_unchecked(
data_type: DataType,
offsets: Buffer<O>,
values: Arc<dyn Array>,
validity: Option<Bitmap>,
) -> Result<Self, ArrowError> {
try_check_offsets_bounds(&offsets, values.len())?;

if validity
.as_ref()
.map_or(false, |validity| validity.len() != offsets.len() - 1)
{
return Err(ArrowError::oos(
"validity mask length must match the number of values",
));
}

let child_data_type = Self::try_get_child(&data_type)?.data_type();
let values_data_type = values.data_type();
if child_data_type != values_data_type {
return Err(ArrowError::oos(
format!("ListArray's child's DataType must match. However, the expected DataType is {child_data_type:?} while it got {values_data_type:?}."),
));
}

Ok(Self {
data_type,
offsets,
values,
validity,
})
}

/// Creates a new [`ListArray`].
///
/// # Panics
/// This function panics iff:
/// * The last offset is not equal to the values' length.
/// * the validity's length is not equal to `offsets.len() - 1`.
/// * The `data_type`'s [`crate::datatypes::PhysicalType`] is not equal to either [`crate::datatypes::PhysicalType::List`] or [`crate::datatypes::PhysicalType::LargeList`].
/// * The `data_type`'s inner field's data type is not equal to `values.data_type`.
/// # Safety
/// This function is unsafe iff:
/// * the offsets are not monotonically increasing
/// # Implementation
/// This function is `O(1)`
pub unsafe fn new_unchecked(
data_type: DataType,
offsets: Buffer<O>,
values: Arc<dyn Array>,
validity: Option<Bitmap>,
) -> Self {
Self::try_new_unchecked(data_type, offsets, values, validity).unwrap()
}
}

impl<O: Offset> ListArray<O> {
/// Returns a slice of this [`ListArray`].
/// # Panics
Expand Down
2 changes: 1 addition & 1 deletion tests/it/array/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn debug() {
}

#[test]
#[should_panic(expected = "The child's datatype must match the inner type of the \'data_type\'")]
#[should_panic]
fn test_nested_panic() {
let values = Buffer::from_slice([1, 2, 3, 4, 5]);
let values = PrimitiveArray::<i32>::from_data(DataType::Int32, values, None);
Expand Down

0 comments on commit bf4f4df

Please sign in to comment.