Skip to content

Commit a44e742

Browse files
authored
Merge pull request #42 from pbower/matrix_upgrade_plus_extras
Matrix and f64 NumericArray enhancements
2 parents f1f98ad + e0fa6e5 commit a44e742

7 files changed

Lines changed: 456 additions & 164 deletions

File tree

src/enums/collections/numeric_array.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{
1616
sync::Arc,
1717
};
1818

19-
use crate::{Bitmask, FloatArray, IntegerArray, MaskedArray};
19+
use crate::{Bitmask, FloatArray, IntegerArray, MaskedArray, Vec64};
2020
use crate::{BooleanArray, StringArray};
2121
use crate::{
2222
enums::{error::MinarrowError, shape_dim::ShapeDim},
@@ -535,6 +535,54 @@ impl NumericArray {
535535
}
536536
}
537537

538+
/// Cast this NumericArray to Float64, staying wrapped as NumericArray.
539+
///
540+
/// If already Float64, returns self unchanged. Otherwise casts element
541+
/// data to f64, preserving the null mask. Uses `Arc::try_unwrap` so that
542+
/// if this is the sole owner of the backing Arc, the old data is consumed
543+
/// and freed rather than cloned.
544+
pub fn cow_into_f64(self) -> Self {
545+
macro_rules! cast_arc {
546+
($arc:expr) => {
547+
match Arc::try_unwrap($arc) {
548+
Ok(owned) => {
549+
let data: Vec64<f64> =
550+
owned.data.as_slice().iter().map(|&v| v as f64).collect();
551+
NumericArray::Float64(Arc::new(FloatArray::new(data, owned.null_mask)))
552+
}
553+
Err(shared) => {
554+
let data: Vec64<f64> =
555+
shared.data.as_slice().iter().map(|&v| v as f64).collect();
556+
NumericArray::Float64(Arc::new(FloatArray::new(
557+
data,
558+
shared.null_mask.clone(),
559+
)))
560+
}
561+
}
562+
};
563+
}
564+
565+
match self {
566+
NumericArray::Float64(_) => self,
567+
NumericArray::Float32(arc) => cast_arc!(arc),
568+
NumericArray::Int32(arc) => cast_arc!(arc),
569+
NumericArray::Int64(arc) => cast_arc!(arc),
570+
NumericArray::UInt32(arc) => cast_arc!(arc),
571+
NumericArray::UInt64(arc) => cast_arc!(arc),
572+
#[cfg(feature = "extended_numeric_types")]
573+
NumericArray::Int8(arc) => cast_arc!(arc),
574+
#[cfg(feature = "extended_numeric_types")]
575+
NumericArray::Int16(arc) => cast_arc!(arc),
576+
#[cfg(feature = "extended_numeric_types")]
577+
NumericArray::UInt8(arc) => cast_arc!(arc),
578+
#[cfg(feature = "extended_numeric_types")]
579+
NumericArray::UInt16(arc) => cast_arc!(arc),
580+
NumericArray::Null => {
581+
NumericArray::Float64(Arc::new(FloatArray::new(Vec64::new(), None)))
582+
}
583+
}
584+
}
585+
538586
/// Convert to FloatArray<f64> using From.
539587
pub fn f64(self) -> Result<FloatArray<f64>, MinarrowError> {
540588
match self {

src/structs/buffer.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ impl<T> Buffer<T> {
200200
}
201201
}
202202

203+
/// Construct a zero-copy buffer as a window into a SharedBuffer.
204+
///
205+
/// The buffer views elements `[offset .. offset + len]` of type T within
206+
/// the shared allocation. The SharedBuffer is cloned (via a refcount bump)
207+
/// so the underlying memory stays alive.
208+
///
209+
/// This is used by Matrix::to_table to create per-column FloatArray
210+
/// buffers that all share the same contiguous allocation.
211+
#[inline]
212+
pub fn from_shared_column(owner: SharedBuffer, offset: usize, len: usize) -> Self {
213+
Self {
214+
storage: Storage::Shared { owner, offset, len },
215+
}
216+
}
217+
203218
/// Construct a zero-copy buffer from an Arc-backed foreign allocation.
204219
///
205220
/// Because all `Minarrow` types work off 64-byte alignment at the outset

0 commit comments

Comments
 (0)