@@ -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 } ;
2020use crate :: { BooleanArray , StringArray } ;
2121use 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 {
0 commit comments