@@ -367,13 +367,6 @@ pub struct TakeOptions {
367367 pub check_bounds : bool ,
368368}
369369
370- #[ inline( always) ]
371- fn maybe_usize < I : ArrowNativeType > ( index : I ) -> Result < usize , ArrowError > {
372- index
373- . to_usize ( )
374- . ok_or_else ( || ArrowError :: ComputeError ( "Cast to usize failed" . to_string ( ) ) )
375- }
376-
377370/// `take` implementation for all primitive arrays
378371///
379372/// This checks if an `indices` slot is populated, and gets the value from `values`
@@ -701,25 +694,32 @@ fn take_fixed_size_binary<IndexType: ArrowPrimitiveType>(
701694 indices : & PrimitiveArray < IndexType > ,
702695 size : i32 ,
703696) -> Result < FixedSizeBinaryArray , ArrowError > {
704- let nulls = values. nulls ( ) ;
705- let array_iter = indices
706- . iter ( )
707- . map ( |idx| {
708- let Some ( idx) = idx else {
709- return Ok ( None ) ;
710- } ;
711-
712- let idx = maybe_usize :: < IndexType :: Native > ( idx) ?;
713- if nulls. map ( |n| n. is_valid ( idx) ) . unwrap_or ( true ) {
714- Ok ( Some ( values. value ( idx) ) )
715- } else {
716- Ok ( None )
717- }
718- } )
719- . collect :: < Result < Vec < _ > , ArrowError > > ( ) ?
720- . into_iter ( ) ;
697+ let size_usize = usize:: try_from ( size) . map_err ( |_| {
698+ ArrowError :: InvalidArgumentError ( format ! ( "Cannot convert size '{}' to usize" , size) )
699+ } ) ?;
700+
701+ let values_buffer = values. values ( ) . as_slice ( ) ;
702+ let mut values_buffer_builder = BufferBuilder :: new ( indices. len ( ) * size_usize) ;
703+ let array_iter = indices. values ( ) . iter ( ) . map ( |idx| {
704+ let offset = idx. as_usize ( ) * size_usize;
705+ & values_buffer[ offset..offset + size_usize]
706+ } ) ;
707+ for slice in array_iter {
708+ values_buffer_builder. append_slice ( slice) ;
709+ }
710+ let values_buffer = values_buffer_builder. finish ( ) ;
711+
712+ let value_nulls = take_nulls ( values. nulls ( ) , indices) ;
713+ let final_nulls = NullBuffer :: union ( value_nulls. as_ref ( ) , indices. nulls ( ) ) ;
714+
715+ let array_data = ArrayDataBuilder :: new ( DataType :: FixedSizeBinary ( size) )
716+ . len ( indices. len ( ) )
717+ . nulls ( final_nulls)
718+ . offset ( 0 )
719+ . add_buffer ( values_buffer)
720+ . build ( ) ?;
721721
722- FixedSizeBinaryArray :: try_from_sparse_iter_with_size ( array_iter , size )
722+ Ok ( FixedSizeBinaryArray :: from ( array_data ) )
723723}
724724
725725/// `take` implementation for dictionary arrays
0 commit comments