@@ -512,18 +512,36 @@ impl<T: ByteViewType + ?Sized> GenericByteViewArray<T> {
512512 } ;
513513 }
514514
515- struct GcCopyGroup {
516- total_buffer_bytes : usize ,
517- total_len : usize ,
518- }
515+ let ( views_buf, data_blocks) = if total_large < i32:: MAX as usize {
516+ // fast path, the entire data fits in a single buffer
517+ // 3) Allocate exactly capacity for all non-inline data
518+ let mut data_buf = Vec :: with_capacity ( total_large) ;
519+
520+ // 4) Iterate over views and process each inline/non-inline view
521+ let views_buf: Vec < u128 > = ( 0 ..len)
522+ . map ( |i| unsafe { self . copy_view_to_buffer ( i, 0 , & mut data_buf) } )
523+ . collect ( ) ;
524+ let data_block = Buffer :: from_vec ( data_buf) ;
525+ let data_blocks = vec ! [ data_block] ;
526+ ( views_buf, data_blocks)
527+ } else {
528+ // slow path, need to split into multiple buffers
529+
530+ struct GcCopyGroup {
531+ total_buffer_bytes : usize ,
532+ total_len : usize ,
533+ }
534+
535+ impl GcCopyGroup {
536+ fn new ( total_buffer_bytes : u32 , total_len : usize ) -> Self {
537+ Self {
538+ total_buffer_bytes : total_buffer_bytes as usize ,
539+ total_len,
540+ }
541+ }
542+ }
519543
520- let mut groups = vec ! [ ] ;
521- let one_group = [ GcCopyGroup {
522- total_buffer_bytes : total_large,
523- total_len : len,
524- } ] ;
525- let gc_copy_groups = if total_large > i32:: MAX as usize {
526- // Slow-path: need to split into multiple copy groups
544+ let mut groups = Vec :: with_capacity ( total_large / ( i32:: MAX as usize ) + 1 ) ;
527545 let mut current_length = 0 ;
528546 let mut current_elements = 0 ;
529547
@@ -532,10 +550,7 @@ impl<T: ByteViewType + ?Sized> GenericByteViewArray<T> {
532550 if len > MAX_INLINE_VIEW_LEN {
533551 if current_length + len > i32:: MAX as u32 {
534552 // Start a new group
535- groups. push ( GcCopyGroup {
536- total_buffer_bytes : current_length as usize ,
537- total_len : current_elements,
538- } ) ;
553+ groups. push ( GcCopyGroup :: new ( current_length, current_elements) ) ;
539554 current_length = 0 ;
540555 current_elements = 0 ;
541556 }
@@ -544,38 +559,37 @@ impl<T: ByteViewType + ?Sized> GenericByteViewArray<T> {
544559 }
545560 }
546561 if current_elements != 0 {
547- groups. push ( GcCopyGroup {
548- total_buffer_bytes : current_length as usize ,
549- total_len : current_elements,
550- } ) ;
562+ groups. push ( GcCopyGroup :: new ( current_length, current_elements) ) ;
551563 }
552- & groups
553- } else {
554- one_group. as_slice ( )
555- } ;
556- debug_assert ! ( gc_copy_groups. len( ) <= i32 :: MAX as usize ) ;
557-
558- // 3) Copy the buffers group by group
559- let mut views_buf = Vec :: with_capacity ( len) ;
560- let mut data_blocks = Vec :: with_capacity ( gc_copy_groups. len ( ) ) ;
561-
562- let mut current_view_idx = 0 ;
563-
564- for ( group_idx, gc_copy_group) in gc_copy_groups. iter ( ) . enumerate ( ) {
565- let mut data_buf = Vec :: with_capacity ( gc_copy_group. total_buffer_bytes ) ;
566-
567- // Directly push views to avoid intermediate Vec allocation
568- for view_idx in current_view_idx..current_view_idx + gc_copy_group. total_len {
569- let view =
570- unsafe { self . copy_view_to_buffer ( view_idx, group_idx as i32 , & mut data_buf) } ;
571- views_buf. push ( view) ;
564+ debug_assert ! ( groups. len( ) <= i32 :: MAX as usize ) ;
565+
566+ // 3) Copy the buffers group by group
567+ let mut views_buf = Vec :: with_capacity ( len) ;
568+ let mut data_blocks = Vec :: with_capacity ( groups. len ( ) ) ;
569+
570+ let mut current_view_idx = 0 ;
571+
572+ for ( group_idx, gc_copy_group) in groups. iter ( ) . enumerate ( ) {
573+ let mut data_buf = Vec :: with_capacity ( gc_copy_group. total_buffer_bytes ) ;
574+
575+ // Directly push views to avoid intermediate Vec allocation
576+ let new_views = ( current_view_idx..current_view_idx + gc_copy_group. total_len ) . map (
577+ |view_idx| {
578+ // safety: the view index came from iterating over valid range
579+ unsafe {
580+ self . copy_view_to_buffer ( view_idx, group_idx as i32 , & mut data_buf)
581+ }
582+ } ,
583+ ) ;
584+ views_buf. extend ( new_views) ;
585+
586+ data_blocks. push ( Buffer :: from_vec ( data_buf) ) ;
587+ current_view_idx += gc_copy_group. total_len ;
572588 }
589+ ( views_buf, data_blocks)
590+ } ;
573591
574- data_blocks. push ( Buffer :: from_vec ( data_buf) ) ;
575- current_view_idx += gc_copy_group. total_len ;
576- }
577-
578- // 4) Wrap up buffers
592+ // 5) Wrap up buffers
579593 let views_scalar = ScalarBuffer :: from ( views_buf) ;
580594
581595 // SAFETY: views_scalar, data_blocks, and nulls are correctly aligned and sized
0 commit comments