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

Commit

Permalink
Simplified new signature of growable API (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao authored Jul 30, 2021
1 parent 8a0c76e commit e08a8a2
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 132 deletions.
38 changes: 38 additions & 0 deletions examples/growable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use arrow2::array::growable::{Growable, GrowablePrimitive};
use arrow2::array::{Array, PrimitiveArray};

fn main() {
// say we have two sorted arrays
let array0 = PrimitiveArray::<i64>::from_slice(&[1, 2, 5]);
let array1 = PrimitiveArray::<i64>::from_slice(&[3, 4, 6]);

// and we found a way to compute the slices that sort them:
// (array_index, start of the slice, length of the slice)
let slices = &[
// [1, 2] from array0
(0, 0, 2),
// [3, 4] from array1
(1, 0, 2),
// [5] from array0
(0, 2, 1),
// [6] from array1
(1, 2, 1),
];

// we can build a new array out of these slices as follows:
// first, declare the growable out of the arrays. Since we are not extending with nulls,
// we use `false`. We also pre-allocate, as we know that we will need all entries.
let capacity = array0.len() + array1.len();
let use_validity = false;
let mut growable = GrowablePrimitive::new(vec![&array0, &array1], use_validity, capacity);

// next, extend the growable:
for slice in slices {
growable.extend(slice.0, slice.1, slice.2);
}
// finally, convert it to the array (this is `O(1)`)
let result: PrimitiveArray<i64> = growable.into();

let expected = PrimitiveArray::<i64>::from_slice(&[1, 2, 3, 4, 5, 6]);
assert_eq!(result, expected);
}
19 changes: 7 additions & 12 deletions src/array/growable/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ pub struct GrowableBinary<'a, O: Offset> {
impl<'a, O: Offset> GrowableBinary<'a, O> {
/// # Panics
/// This function panics if any of the `arrays` is not downcastable to `PrimitiveArray<T>`.
pub fn new(arrays: &[&'a dyn Array], mut use_validity: bool, capacity: usize) -> Self {
pub fn new(arrays: Vec<&'a BinaryArray<O>>, mut use_validity: bool, capacity: usize) -> Self {
// if any of the arrays has nulls, insertions from any array requires setting bits
// as there is at least one array with nulls.
if arrays.iter().any(|array| array.null_count() > 0) {
if !use_validity & arrays.iter().any(|array| array.null_count() > 0) {
use_validity = true;
};

Expand All @@ -38,11 +38,6 @@ impl<'a, O: Offset> GrowableBinary<'a, O> {
.map(|array| build_extend_null_bits(*array, use_validity))
.collect();

let arrays = arrays
.iter()
.map(|array| array.as_any().downcast_ref::<BinaryArray<O>>().unwrap())
.collect::<Vec<_>>();

let mut offsets = MutableBuffer::with_capacity(capacity + 1);
let length = O::default();
unsafe { offsets.push_unchecked(length) };
Expand Down Expand Up @@ -114,7 +109,7 @@ mod tests {
fn test_variable_sized_validity() {
let array = BinaryArray::<i32>::from_iter(vec![Some("a"), Some("bc"), None, Some("defh")]);

let mut a = GrowableBinary::new(&[&array], false, 0);
let mut a = GrowableBinary::new(vec![&array], false, 0);

a.extend(0, 1, 2);

Expand All @@ -131,7 +126,7 @@ mod tests {
let array = BinaryArray::<i32>::from_iter(vec![Some("a"), Some("bc"), None, Some("defh")]);
let array = array.slice(1, 3);

let mut a = GrowableBinary::new(&[&array], false, 0);
let mut a = GrowableBinary::new(vec![&array], false, 0);

a.extend(0, 0, 3);

Expand All @@ -146,7 +141,7 @@ mod tests {
let array = BinaryArray::<i32>::from_iter(vec![Some("a"), Some("bc"), None, Some("defh")]);
let array = array.slice(1, 3);

let mut a = GrowableBinary::new(&[&array], false, 0);
let mut a = GrowableBinary::new(vec![&array], false, 0);

a.extend(0, 0, 3);

Expand All @@ -161,7 +156,7 @@ mod tests {
let array1 = BinaryArray::<i32>::from_slice(vec![b"hello", b"world"]);
let array2 = BinaryArray::<i32>::from_iter(vec![Some("1"), None]);

let mut a = GrowableBinary::new(&[&array1, &array2], false, 5);
let mut a = GrowableBinary::new(vec![&array1, &array2], false, 5);

a.extend(0, 0, 2);
a.extend(1, 0, 2);
Expand All @@ -178,7 +173,7 @@ mod tests {
let array = BinaryArray::<i32>::from_iter(vec![Some("a"), Some("bc"), None, Some("defh")]);
let array = array.slice(1, 3);

let mut a = GrowableBinary::new(&[&array], true, 0);
let mut a = GrowableBinary::new(vec![&array], true, 0);

a.extend(0, 1, 2);
a.extend_validity(1);
Expand Down
13 changes: 3 additions & 10 deletions src/array/growable/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ pub struct GrowableBoolean<'a> {
}

impl<'a> GrowableBoolean<'a> {
/// # Panics
/// This function panics if any of the `arrays` is not downcastable to `PrimitiveArray<T>`.
pub fn new(arrays: &[&'a dyn Array], mut use_validity: bool, capacity: usize) -> Self {
pub fn new(arrays: Vec<&'a BooleanArray>, mut use_validity: bool, capacity: usize) -> Self {
// if any of the arrays has nulls, insertions from any array requires setting bits
// as there is at least one array with nulls.
if arrays.iter().any(|array| array.null_count() > 0) {
if !use_validity & arrays.iter().any(|array| array.null_count() > 0) {
use_validity = true;
};

Expand All @@ -35,11 +33,6 @@ impl<'a> GrowableBoolean<'a> {
.map(|array| build_extend_null_bits(*array, use_validity))
.collect();

let arrays = arrays
.iter()
.map(|array| array.as_any().downcast_ref::<BooleanArray>().unwrap())
.collect::<Vec<_>>();

Self {
arrays,
values: MutableBitmap::with_capacity(capacity),
Expand Down Expand Up @@ -94,7 +87,7 @@ mod tests {
fn test_bool() {
let array = BooleanArray::from(vec![Some(false), Some(true), None, Some(false)]);

let mut a = GrowableBoolean::new(&[&array], false, 0);
let mut a = GrowableBoolean::new(vec![&array], false, 0);

a.extend(0, 1, 2);

Expand Down
28 changes: 10 additions & 18 deletions src/array/growable/fixed_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ pub struct GrowableFixedSizeBinary<'a> {
}

impl<'a> GrowableFixedSizeBinary<'a> {
/// # Panics
/// This function panics if any of the `arrays` is not downcastable to `FixedSizeBinaryArray`.
pub fn new(arrays: &[&'a dyn Array], mut use_validity: bool, capacity: usize) -> Self {
pub fn new(
arrays: Vec<&'a FixedSizeBinaryArray>,
mut use_validity: bool,
capacity: usize,
) -> Self {
// if any of the arrays has nulls, insertions from any array requires setting bits
// as there is at least one array with nulls.
if arrays.iter().any(|array| array.null_count() > 0) {
Expand All @@ -37,16 +39,6 @@ impl<'a> GrowableFixedSizeBinary<'a> {
.map(|array| build_extend_null_bits(*array, use_validity))
.collect();

let arrays = arrays
.iter()
.map(|array| {
array
.as_any()
.downcast_ref::<FixedSizeBinaryArray>()
.unwrap()
})
.collect::<Vec<_>>();

let size = *FixedSizeBinaryArray::get_size(arrays[0].data_type()) as usize;
Self {
arrays,
Expand Down Expand Up @@ -115,7 +107,7 @@ mod tests {
let array =
FixedSizeBinaryArray::from_iter(vec![Some(b"ab"), Some(b"bc"), None, Some(b"de")], 2);

let mut a = GrowableFixedSizeBinary::new(&[&array], false, 0);
let mut a = GrowableFixedSizeBinary::new(vec![&array], false, 0);

a.extend(0, 1, 2);

Expand All @@ -133,7 +125,7 @@ mod tests {
FixedSizeBinaryArray::from_iter(vec![Some(b"ab"), Some(b"bc"), None, Some(b"fh")], 2);
let array = array.slice(1, 3);

let mut a = GrowableFixedSizeBinary::new(&[&array], false, 0);
let mut a = GrowableFixedSizeBinary::new(vec![&array], false, 0);

a.extend(0, 0, 3);

Expand All @@ -148,7 +140,7 @@ mod tests {
let array1 = FixedSizeBinaryArray::from_iter(vec![Some("hello"), Some("world")], 5);
let array2 = FixedSizeBinaryArray::from_iter(vec![Some("12345"), None], 5);

let mut a = GrowableFixedSizeBinary::new(&[&array1, &array2], false, 5);
let mut a = GrowableFixedSizeBinary::new(vec![&array1, &array2], false, 5);

a.extend(0, 0, 2);
a.extend(1, 0, 2);
Expand All @@ -168,7 +160,7 @@ mod tests {
FixedSizeBinaryArray::from_iter(vec![Some("aa"), Some("bc"), None, Some("fh")], 2);
let array = array.slice(1, 3);

let mut a = GrowableFixedSizeBinary::new(&[&array], true, 0);
let mut a = GrowableFixedSizeBinary::new(vec![&array], true, 0);

a.extend(0, 1, 2);
a.extend_validity(1);
Expand All @@ -186,7 +178,7 @@ mod tests {
let array = array.slice(1, 2);
// = [[0, 1], [0, 2]] due to the offset = 1

let mut a = GrowableFixedSizeBinary::new(&[&array], false, 0);
let mut a = GrowableFixedSizeBinary::new(vec![&array], false, 0);

a.extend(0, 1, 1);
a.extend(0, 0, 1);
Expand Down
21 changes: 6 additions & 15 deletions src/array/growable/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ pub struct GrowableList<'a, O: Offset> {
}

impl<'a, O: Offset> GrowableList<'a, O> {
/// # Panics
/// This function panics if any of the `arrays` is not downcastable to `PrimitiveArray<T>`.
pub fn new(arrays: &[&'a dyn Array], mut use_validity: bool, capacity: usize) -> Self {
pub fn new(arrays: Vec<&'a ListArray<O>>, mut use_validity: bool, capacity: usize) -> Self {
// if any of the arrays has nulls, insertions from any array requires setting bits
// as there is at least one array with nulls.
if use_validity || arrays.iter().any(|array| array.null_count() > 0) {
if !use_validity & arrays.iter().any(|array| array.null_count() > 0) {
use_validity = true;
};

Expand All @@ -81,11 +79,6 @@ impl<'a, O: Offset> GrowableList<'a, O> {
.map(|array| build_extend_null_bits(*array, use_validity))
.collect();

let arrays = arrays
.iter()
.map(|array| array.as_any().downcast_ref::<ListArray<O>>().unwrap())
.collect::<Vec<_>>();

let inner = arrays
.iter()
.map(|array| array.values().as_ref())
Expand Down Expand Up @@ -176,7 +169,7 @@ mod tests {

let array = create_list_array(data);

let mut a = GrowableList::new(&[&array], false, 0);
let mut a = GrowableList::new(vec![&array], false, 0);
a.extend(0, 0, 1);

let result: ListArray<i32> = a.into();
Expand All @@ -197,7 +190,7 @@ mod tests {
let array = create_list_array(data);
let array = array.slice(1, 2);

let mut a = GrowableList::new(&[&array], false, 0);
let mut a = GrowableList::new(vec![&array], false, 0);
a.extend(0, 1, 1);

let result: ListArray<i32> = a.into();
Expand All @@ -218,7 +211,7 @@ mod tests {
let array = create_list_array(data);
let array = array.slice(1, 2);

let mut a = GrowableList::new(&[&array], false, 0);
let mut a = GrowableList::new(vec![&array], false, 0);
a.extend(0, 1, 1);

let result: ListArray<i32> = a.into();
Expand All @@ -245,9 +238,7 @@ mod tests {
];
let array_2 = create_list_array(data_2);

let arrays: Vec<&dyn Array> = vec![&array_1, &array_2];

let mut a = GrowableList::new(&arrays, false, 6);
let mut a = GrowableList::new(vec![&array_1, &array_2], false, 6);
a.extend(0, 0, 2);
a.extend(1, 1, 1);

Expand Down
Loading

0 comments on commit e08a8a2

Please sign in to comment.