Skip to content

Commit

Permalink
Fix test and more for review
Browse files Browse the repository at this point in the history
  • Loading branch information
viirya committed Nov 16, 2022
1 parent cee4d48 commit e78aecd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 19 deletions.
43 changes: 32 additions & 11 deletions arrow-array/src/array/primitive_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,6 @@ impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
/// Returns `PrimitiveBuilder` of this primitive array for mutating its values if the underlying
/// data buffer is not shared by others.
pub fn into_builder(self) -> Result<PrimitiveBuilder<T>, Self> {
let null_buffer = self
.data
.null_buffer()
.cloned()
.and_then(|b| b.into_mutable().ok());

let len = self.len();
let null_bit_buffer = self.data.null_buffer().cloned();

Expand All @@ -537,13 +531,36 @@ impl<T: ArrowPrimitiveType> PrimitiveArray<T> {

drop(self.data);

let builder = buffer
.into_mutable()
.map(|buffer| PrimitiveBuilder::<T>::new_from_buffer(buffer, null_buffer));
let try_mutable_null_buffer = match null_bit_buffer {
None => Ok(None),
Some(null_buffer) => {
// Null buffer exists, tries to make it mutable
null_buffer.into_mutable().map(|b| Some(b))
}
};

let try_mutable_buffers = if try_mutable_null_buffer.is_ok() {
// Got mutable null buffer, tries to get mutable value buffer
let mutable_null_buffer = try_mutable_null_buffer.unwrap();
let try_mutable_buffer = buffer.into_mutable();

// try_mutable_buffer.map(...).map_err(...) doesn't work as the compiler complains
// mutable_null_buffer is moved into map closure.
match try_mutable_buffer {
Ok(mutable_buffer) => Ok(PrimitiveBuilder::<T>::new_from_buffer(
mutable_buffer,
mutable_null_buffer,
)),
Err(buffer) => Err((buffer, mutable_null_buffer.map(|b| b.into()))),
}
} else {
// Unable to get mutable null buffer
Err((buffer, Some(try_mutable_null_buffer.unwrap_err())))
};

match builder {
match try_mutable_buffers {
Ok(builder) => Ok(builder),
Err(buffer) => {
Err((buffer, null_bit_buffer)) => {
let builder = ArrayData::builder(T::DATA_TYPE)
.len(len)
.add_buffer(buffer)
Expand Down Expand Up @@ -2058,5 +2075,9 @@ mod tests {
let expected: Int32Array = vec![3, 5, 7].into_iter().map(Some).collect();

assert_eq!(expected, c);

let array: Int32Array = Int32Array::from(vec![Some(5), Some(7), None]);
let c = array.unary_mut(|x| x * 2 + 1).unwrap();
assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
}
}
4 changes: 2 additions & 2 deletions arrow-array/src/builder/boolean_buffer_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ impl BooleanBufferBuilder {
Self { buffer, len: 0 }
}

pub fn new_from_buffer(buffer: MutableBuffer) -> Self {
Self { buffer, len: 0 }
pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
Self { buffer, len }
}

#[inline]
Expand Down
17 changes: 15 additions & 2 deletions arrow-array/src/builder/null_buffer_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,22 @@ impl NullBufferBuilder {
}
}

/// Creates a new builder with given length.
pub fn new_with_len(len: usize) -> Self {
Self {
bitmap_builder: None,
len,
capacity: len,
}
}

/// Creates a new builder from a `MutableBuffer`.
pub fn new_from_buffer(buffer: MutableBuffer, len: usize, capacity: usize) -> Self {
let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer));
pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
let capacity = buffer.len() * 8;

assert!(len < capacity);

let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
Self {
bitmap_builder,
len,
Expand Down
6 changes: 2 additions & 4 deletions arrow-array/src/builder/primitive_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,13 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
values_buffer: MutableBuffer,
null_buffer: Option<MutableBuffer>,
) -> Self {
let capacity = values_buffer.capacity();

let values_builder = BufferBuilder::<T::Native>::new_from_buffer(values_buffer);

let null_buffer_builder = null_buffer
.map(|buffer| {
NullBufferBuilder::new_from_buffer(buffer, values_builder.len(), capacity)
NullBufferBuilder::new_from_buffer(buffer, values_builder.len())
})
.unwrap_or_else(|| NullBufferBuilder::new(capacity));
.unwrap_or_else(|| NullBufferBuilder::new_with_len(values_builder.len()));

Self {
values_builder,
Expand Down

0 comments on commit e78aecd

Please sign in to comment.