@@ -14,7 +14,6 @@ use std::{
1414 fmt, io,
1515 os:: { fd:: RawFd , unix:: fs:: symlink} ,
1616 path:: { Path , PathBuf } ,
17- sync:: { Arc , RwLock } ,
1817 time:: { Duration , Instant } ,
1918} ;
2019
@@ -28,7 +27,7 @@ use nix::{
2827 unistd:: { close, linkat, mkdir, symlinkat} ,
2928} ;
3029use postblit:: TriggerScope ;
31- use rayon:: iter:: { IntoParallelRefIterator , ParallelIterator } ;
30+ use rayon:: iter:: { IntoParallelIterator , ParallelIterator } ;
3231use stone:: { payload:: layout, read:: PayloadKind } ;
3332use thiserror:: Error ;
3433use tui:: { MultiProgress , ProgressBar , ProgressStyle , Styled } ;
@@ -628,7 +627,7 @@ impl Client {
628627 progress. tick ( ) ;
629628
630629 let now = Instant :: now ( ) ;
631- let stats = Arc :: new ( RwLock :: new ( BlitStats :: default ( ) ) ) ;
630+ let mut stats = BlitStats :: default ( ) ;
632631
633632 let tree = self . vfs ( packages) ?;
634633
@@ -651,9 +650,12 @@ impl Client {
651650 let root_dir = fcntl:: open ( & blit_target, OFlag :: O_DIRECTORY | OFlag :: O_RDONLY , Mode :: empty ( ) ) ?;
652651
653652 if let Element :: Directory ( _, _, children) = root {
654- children
655- . par_iter ( )
656- . try_for_each ( |child| self . blit_element ( root_dir, cache_fd, child, & progress, & stats) ) ?;
653+ stats = stats. merge (
654+ children
655+ . into_par_iter ( )
656+ . map ( |child| self . blit_element ( root_dir, cache_fd, child, & progress) )
657+ . try_reduce ( BlitStats :: default, |a, b| Ok ( a. merge ( b) ) ) ?,
658+ ) ;
657659 }
658660
659661 close ( root_dir) ?;
@@ -662,8 +664,7 @@ impl Client {
662664 progress. finish_and_clear ( ) ;
663665
664666 let elapsed = now. elapsed ( ) ;
665- let stats_raw = stats. write ( ) . unwrap ( ) ;
666- let num_entries = stats_raw. num_entries ( ) ;
667+ let num_entries = stats. num_entries ( ) ;
667668
668669 println ! (
669670 "\n {} entries blitted in {} {}" ,
@@ -682,32 +683,35 @@ impl Client {
682683 & self ,
683684 parent : RawFd ,
684685 cache : RawFd ,
685- element : & Element < ' _ , PendingFile > ,
686+ element : Element < ' _ , PendingFile > ,
686687 progress : & ProgressBar ,
687- stats : & Arc < RwLock < BlitStats > > ,
688- ) -> Result < ( ) , Error > {
688+ ) -> Result < BlitStats , Error > {
689+ let mut stats = BlitStats :: default ( ) ;
690+
689691 progress. inc ( 1 ) ;
690692 match element {
691693 Element :: Directory ( name, item, children) => {
692694 // Construct within the parent
693- self . blit_element_item ( parent, cache, name, item, stats) ?;
695+ self . blit_element_item ( parent, cache, name, item, & mut stats) ?;
694696
695697 // open the new dir
696- let newdir = fcntl:: openat (
697- parent ,
698- name . to_owned ( ) ,
699- OFlag :: O_RDONLY | OFlag :: O_DIRECTORY ,
700- Mode :: empty ( ) ,
701- ) ? ;
702- children
703- . par_iter ( )
704- . try_for_each ( |child| self . blit_element ( newdir , cache , child , progress , stats ) ) ? ;
698+ let newdir = fcntl:: openat ( parent , name , OFlag :: O_RDONLY | OFlag :: O_DIRECTORY , Mode :: empty ( ) ) ? ;
699+
700+ stats = stats . merge (
701+ children
702+ . into_par_iter ( )
703+ . map ( |child| self . blit_element ( newdir , cache , child , progress ) )
704+ . try_reduce ( BlitStats :: default , |a , b| Ok ( a . merge ( b ) ) ) ? ,
705+ ) ;
706+
705707 close ( newdir) ?;
706- Ok ( ( ) )
708+
709+ Ok ( stats)
707710 }
708711 Element :: Child ( name, item) => {
709- self . blit_element_item ( parent, cache, name, item, stats) ?;
710- Ok ( ( ) )
712+ self . blit_element_item ( parent, cache, name, item, & mut stats) ?;
713+
714+ Ok ( stats)
711715 }
712716 }
713717 }
@@ -726,7 +730,7 @@ impl Client {
726730 cache : RawFd ,
727731 subpath : & str ,
728732 item : & PendingFile ,
729- stats : & Arc < RwLock < BlitStats > > ,
733+ stats : & mut BlitStats ,
730734 ) -> Result < ( ) , Error > {
731735 match & item. layout . entry {
732736 layout:: Entry :: Regular ( id, _) => {
@@ -772,24 +776,15 @@ impl Client {
772776 }
773777 }
774778
775- let mut stats_raw = stats. write ( ) . unwrap ( ) ;
776- {
777- stats_raw. num_files += 1 ;
778- }
779+ stats. num_files += 1 ;
779780 }
780781 layout:: Entry :: Symlink ( source, _) => {
781782 symlinkat ( source. as_str ( ) , Some ( parent) , subpath) ?;
782- let mut stats_raw = stats. write ( ) . unwrap ( ) ;
783- {
784- stats_raw. num_symlinks += 1 ;
785- }
783+ stats. num_symlinks += 1 ;
786784 }
787785 layout:: Entry :: Directory ( _) => {
788786 mkdirat ( parent, subpath, Mode :: from_bits_truncate ( item. layout . mode ) ) ?;
789- let mut stats_raw = stats. write ( ) . unwrap ( ) ;
790- {
791- stats_raw. num_dirs += 1 ;
792- }
787+ stats. num_dirs += 1 ;
793788 }
794789
795790 // unimplemented
@@ -998,14 +993,22 @@ fn build_registry(
998993 Ok ( registry)
999994}
1000995
1001- #[ derive( Debug , Default ) ]
996+ #[ derive( Debug , Clone , Copy , Default ) ]
1002997struct BlitStats {
1003998 num_files : u64 ,
1004999 num_symlinks : u64 ,
10051000 num_dirs : u64 ,
10061001}
10071002
10081003impl BlitStats {
1004+ fn merge ( self , other : Self ) -> Self {
1005+ Self {
1006+ num_files : self . num_files + other. num_files ,
1007+ num_symlinks : self . num_symlinks + other. num_symlinks ,
1008+ num_dirs : self . num_dirs + other. num_dirs ,
1009+ }
1010+ }
1011+
10091012 fn num_entries ( & self ) -> u64 {
10101013 self . num_files + self . num_symlinks + self . num_dirs
10111014 }
0 commit comments