Skip to content

Commit e2ebb23

Browse files
alambvegarsti
andauthored
Add example to convert PrimitiveArray to a Vec (#8771)
# Which issue does this PR close? - related to apache/datafusion#18424 # Rationale for this change It may not be obvious how to convert certain Arrow arrays to/from Vec without copying for manipulation, so let's add an example # What changes are included in this PR? 1. Add note about zero copy arrays 2. Add examples of modifying a primitive array using zero-copy conversion to/from Vec # Are these changes tested? By CI # Are there any user-facing changes? Docs only, no functional change --------- Co-authored-by: Vegard Stikbakke <[email protected]>
1 parent a30890e commit e2ebb23

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

arrow-array/src/array/primitive_array.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ pub use crate::types::ArrowPrimitiveType;
493493
///
494494
/// # Example: From a Vec
495495
///
496+
/// *Note*: Converting a `Vec` to a `PrimitiveArray` does not copy the data.
497+
/// The new `PrimitiveArray` uses the same underlying allocation from the `Vec`.
498+
///
496499
/// ```
497500
/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
498501
/// let arr: PrimitiveArray<Int32Type> = vec![1, 2, 3, 4].into();
@@ -501,6 +504,33 @@ pub use crate::types::ArrowPrimitiveType;
501504
/// assert_eq!(arr.values(), &[1, 2, 3, 4])
502505
/// ```
503506
///
507+
/// # Example: To a `Vec<T>`
508+
///
509+
/// *Note*: In some cases, converting `PrimitiveArray` to a `Vec` is zero-copy
510+
/// and does not copy the data (see [`Buffer::into_vec`] for conditions). In
511+
/// such cases, the `Vec` will use the same underlying memory allocation from
512+
/// the `PrimitiveArray`.
513+
///
514+
/// The Rust compiler generates highly optimized code for operations on
515+
/// Vec, so using a Vec can often be faster than using a PrimitiveArray directly.
516+
///
517+
/// ```
518+
/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
519+
/// let arr = PrimitiveArray::<Int32Type>::from(vec![1, 2, 3, 4]);
520+
/// let starting_ptr = arr.values().as_ptr();
521+
/// // split into its parts
522+
/// let (datatype, buffer, nulls) = arr.into_parts();
523+
/// // Convert the buffer to a Vec<i32> (zero copy)
524+
/// // (note this requires that there are no other references)
525+
/// let mut vec: Vec<i32> = buffer.into();
526+
/// vec[2] = 300;
527+
/// // put the parts back together
528+
/// let arr = PrimitiveArray::<Int32Type>::try_new(vec.into(), nulls).unwrap();
529+
/// assert_eq!(arr.values(), &[1, 2, 300, 4]);
530+
/// // The same allocation was used
531+
/// assert_eq!(starting_ptr, arr.values().as_ptr());
532+
/// ```
533+
///
504534
/// # Example: From an optional Vec
505535
///
506536
/// ```

arrow-buffer/src/buffer/immutable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ impl Buffer {
388388
/// # Errors
389389
///
390390
/// Returns `Err(self)` if
391-
/// 1. this buffer does not have the same [`Layout`] as the destination Vec
392-
/// 2. contains a non-zero offset
391+
/// 1. The buffer does not have the same [`Layout`] as the destination Vec
392+
/// 2. The buffer contains a non-zero offset
393393
/// 3. The buffer is shared
394394
pub fn into_vec<T: ArrowNativeType>(self) -> Result<Vec<T>, Self> {
395395
let layout = match self.data.deallocation() {

0 commit comments

Comments
 (0)