Skip to content

Commit

Permalink
impl From<ScalarBuffer<T>> for Vec<T> (#5518)
Browse files Browse the repository at this point in the history
* impl `From<ScalarBuffer<T>>` for `Vec<T>`

* Remove layout test, prevented by `miri`
  • Loading branch information
mbrobbel authored Mar 16, 2024
1 parent ae42b3b commit 7e5f523
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions arrow-buffer/src/buffer/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ impl<T: ArrowNativeType> From<Vec<T>> for ScalarBuffer<T> {
}
}

impl<T: ArrowNativeType> From<ScalarBuffer<T>> for Vec<T> {
fn from(value: ScalarBuffer<T>) -> Self {
value
.buffer
.into_vec()
.unwrap_or_else(|buffer| buffer.typed_data::<T>().into())
}
}

impl<T: ArrowNativeType> From<BufferBuilder<T>> for ScalarBuffer<T> {
fn from(mut value: BufferBuilder<T>) -> Self {
let len = value.len();
Expand Down Expand Up @@ -208,6 +217,8 @@ impl<T: ArrowNativeType> PartialEq<ScalarBuffer<T>> for Vec<T> {

#[cfg(test)]
mod tests {
use std::{ptr::NonNull, sync::Arc};

use super::*;

#[test]
Expand Down Expand Up @@ -284,4 +295,45 @@ mod tests {
let scalar_buffer = ScalarBuffer::from(buffer_builder);
assert_eq!(scalar_buffer.as_ref(), input);
}

#[test]
fn into_vec() {
let input = vec![1u8, 2, 3, 4];

// No copy
let input_buffer = Buffer::from_vec(input.clone());
let input_ptr = input_buffer.as_ptr();
let input_len = input_buffer.len();
let scalar_buffer = ScalarBuffer::<u8>::new(input_buffer, 0, input_len);
let vec = Vec::from(scalar_buffer);
assert_eq!(vec.as_slice(), input.as_slice());
assert_eq!(vec.as_ptr(), input_ptr);

// Custom allocation - makes a copy
let mut input_clone = input.clone();
let input_ptr = NonNull::new(input_clone.as_mut_ptr()).unwrap();
let dealloc = Arc::new(());
let buffer =
unsafe { Buffer::from_custom_allocation(input_ptr, input_clone.len(), dealloc as _) };
let scalar_buffer = ScalarBuffer::<u8>::new(buffer, 0, input.len());
let vec = Vec::from(scalar_buffer);
assert_eq!(vec, input.as_slice());
assert_ne!(vec.as_ptr(), input_ptr.as_ptr());

// Offset - makes a copy
let input_buffer = Buffer::from_vec(input.clone());
let input_ptr = input_buffer.as_ptr();
let input_len = input_buffer.len();
let scalar_buffer = ScalarBuffer::<u8>::new(input_buffer, 1, input_len - 1);
let vec = Vec::from(scalar_buffer);
assert_eq!(vec.as_slice(), &input[1..]);
assert_ne!(vec.as_ptr(), input_ptr);

// Inner buffer Arc ref count != 0 - makes a copy
let buffer = Buffer::from_slice_ref(input.as_slice());
let scalar_buffer = ScalarBuffer::<u8>::new(buffer, 0, input.len());
let vec = Vec::from(scalar_buffer);
assert_eq!(vec, input.as_slice());
assert_ne!(vec.as_ptr(), input.as_ptr());
}
}

0 comments on commit 7e5f523

Please sign in to comment.