@@ -521,53 +521,50 @@ impl S3 {
521521
522522        let  mut  async_writer = self . client . put_multipart ( location) . await ?; 
523523
524-         // /* `abort_multipart()` has been removed */ 
525-         // let close_multipart = |err| async move { 
526-         //     error!("multipart upload failed. {:?}", err); 
527-         //     self.client 
528-         //         .abort_multipart(&key.into(), &multipart_id) 
529-         //         .await 
530-         // }; 
531- 
532524        let  meta = file. metadata ( ) . await ?; 
533525        let  total_size = meta. len ( )  as  usize ; 
534526        if  total_size < MIN_MULTIPART_UPLOAD_SIZE  { 
535527            let  mut  data = Vec :: new ( ) ; 
536528            file. read_to_end ( & mut  data) . await ?; 
537529            self . client . put ( location,  data. into ( ) ) . await ?; 
538-             // async_writer.put_part(data.into()).await?; 
539-             // async_writer.complete().await?; 
530+ 
540531            return  Ok ( ( ) ) ; 
541532        }  else  { 
542-             let  mut  data = Vec :: new ( ) ; 
543-             file. read_to_end ( & mut  data) . await ?; 
533+             let  mut  buf = [ 0 ;  MIN_MULTIPART_UPLOAD_SIZE  *  2 ] ; 
544534
545-             // let mut upload_parts = Vec::new(); 
535+             let  mut  position = 0 ; 
536+             let  mut  tasks = FuturesUnordered :: new ( ) ; 
546537
547-             let  has_final_partial_part = total_size % MIN_MULTIPART_UPLOAD_SIZE  > 0 ; 
548-             let  num_full_parts = total_size / MIN_MULTIPART_UPLOAD_SIZE ; 
549-             let  total_parts = num_full_parts + if  has_final_partial_part {  1  }  else  {  0  } ; 
538+             while  position < total_size { 
539+                 // Calculate how much to read in this iteration 
540+                 let  bytes_to_read = std:: cmp:: min ( buf. len ( ) ,  total_size - position) ; 
541+                 let  buffer_slice = & mut  buf[ ..bytes_to_read] ; 
550542
551-             // Upload each part 
552-             for  part_number in  0 ..( total_parts)  { 
553-                 let  start_pos = part_number *  MIN_MULTIPART_UPLOAD_SIZE ; 
554-                 let  end_pos = if  part_number == num_full_parts && has_final_partial_part { 
555-                     // Last part might be smaller than 5MB (which is allowed) 
556-                     total_size
557-                 }  else  { 
558-                     // All other parts must be at least 5MB 
559-                     start_pos + MIN_MULTIPART_UPLOAD_SIZE 
560-                 } ; 
543+                 // Read exactly that many bytes 
544+                 match  file. read_exact ( buffer_slice) . await  { 
545+                     Ok ( _)  => { } 
546+                     Err ( e)  => return  Err ( e. into ( ) ) , 
547+                 } 
561548
562-                 // Extract this part's data 
563-                 let  part_data = data[ start_pos..end_pos] . to_vec ( ) ; 
549+                 position += bytes_to_read; 
564550
565551                // Upload the part 
566-                 async_writer. put_part ( part_data. into ( ) ) . await ?; 
552+                 tasks. push ( tokio:: spawn ( 
553+                     async_writer. put_part ( buffer_slice. to_vec ( ) . into ( ) ) , 
554+                 ) ) ; 
555+             } 
567556
568-                 // upload_parts.push(part_number as u64 + 1); 
557+             while  let  Some ( res)  = tasks. next ( ) . await  { 
558+                 res??; 
569559            } 
570-             async_writer. complete ( ) . await ?; 
560+ 
561+             match  async_writer. complete ( ) . await  { 
562+                 Ok ( _)  => { } 
563+                 Err ( e)  => { 
564+                     error ! ( "Failed to complete multipart upload: {:?}" ,  e) ; 
565+                     async_writer. abort ( ) . await ?; 
566+                 } 
567+             } ; 
571568        } 
572569        Ok ( ( ) ) 
573570    } 
0 commit comments