Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion src/enums/collections/numeric_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
sync::Arc,
};

use crate::{Bitmask, FloatArray, IntegerArray, MaskedArray};
use crate::{Bitmask, FloatArray, IntegerArray, MaskedArray, Vec64};
use crate::{BooleanArray, StringArray};
use crate::{
enums::{error::MinarrowError, shape_dim::ShapeDim},
Expand Down Expand Up @@ -535,6 +535,54 @@ impl NumericArray {
}
}

/// Cast this NumericArray to Float64, staying wrapped as NumericArray.
///
/// If already Float64, returns self unchanged. Otherwise casts element
/// data to f64, preserving the null mask. Uses `Arc::try_unwrap` so that
/// if this is the sole owner of the backing Arc, the old data is consumed
/// and freed rather than cloned.
pub fn cow_into_f64(self) -> Self {
macro_rules! cast_arc {
($arc:expr) => {
match Arc::try_unwrap($arc) {
Ok(owned) => {
let data: Vec64<f64> =
owned.data.as_slice().iter().map(|&v| v as f64).collect();
NumericArray::Float64(Arc::new(FloatArray::new(data, owned.null_mask)))
}
Err(shared) => {
let data: Vec64<f64> =
shared.data.as_slice().iter().map(|&v| v as f64).collect();
NumericArray::Float64(Arc::new(FloatArray::new(
data,
shared.null_mask.clone(),
)))
}
}
};
}

match self {
NumericArray::Float64(_) => self,
NumericArray::Float32(arc) => cast_arc!(arc),
NumericArray::Int32(arc) => cast_arc!(arc),
NumericArray::Int64(arc) => cast_arc!(arc),
NumericArray::UInt32(arc) => cast_arc!(arc),
NumericArray::UInt64(arc) => cast_arc!(arc),
#[cfg(feature = "extended_numeric_types")]
NumericArray::Int8(arc) => cast_arc!(arc),
#[cfg(feature = "extended_numeric_types")]
NumericArray::Int16(arc) => cast_arc!(arc),
#[cfg(feature = "extended_numeric_types")]
NumericArray::UInt8(arc) => cast_arc!(arc),
#[cfg(feature = "extended_numeric_types")]
NumericArray::UInt16(arc) => cast_arc!(arc),
NumericArray::Null => {
NumericArray::Float64(Arc::new(FloatArray::new(Vec64::new(), None)))
}
}
}

/// Convert to FloatArray<f64> using From.
pub fn f64(self) -> Result<FloatArray<f64>, MinarrowError> {
match self {
Expand Down
15 changes: 15 additions & 0 deletions src/structs/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,21 @@ impl<T> Buffer<T> {
}
}

/// Construct a zero-copy buffer as a window into a SharedBuffer.
///
/// The buffer views elements `[offset .. offset + len]` of type T within
/// the shared allocation. The SharedBuffer is cloned (via a refcount bump)
/// so the underlying memory stays alive.
///
/// This is used by Matrix::to_table to create per-column FloatArray
/// buffers that all share the same contiguous allocation.
#[inline]
pub fn from_shared_column(owner: SharedBuffer, offset: usize, len: usize) -> Self {
Self {
storage: Storage::Shared { owner, offset, len },
}
}

/// Construct a zero-copy buffer from an Arc-backed foreign allocation.
///
/// Because all `Minarrow` types work off 64-byte alignment at the outset
Expand Down
Loading
Loading