@@ -14,6 +14,7 @@ use std::{
1414 fmt, io,
1515 os:: { fd:: RawFd , unix:: fs:: symlink} ,
1616 path:: { Path , PathBuf } ,
17+ sync:: { Arc , RwLock } ,
1718 time:: { Duration , Instant } ,
1819} ;
1920
@@ -27,6 +28,7 @@ use nix::{
2728 unistd:: { close, linkat, mkdir, symlinkat} ,
2829} ;
2930use postblit:: TriggerScope ;
31+ use rayon:: iter:: { IntoParallelRefIterator , ParallelIterator } ;
3032use stone:: { payload:: layout, read:: PayloadKind } ;
3133use thiserror:: Error ;
3234use tui:: { MultiProgress , ProgressBar , ProgressStyle , Styled } ;
@@ -626,7 +628,7 @@ impl Client {
626628 progress. tick ( ) ;
627629
628630 let now = Instant :: now ( ) ;
629- let mut stats = BlitStats :: default ( ) ;
631+ let stats = Arc :: new ( RwLock :: new ( BlitStats :: default ( ) ) ) ;
630632
631633 let tree = self . vfs ( packages) ?;
632634
@@ -649,9 +651,9 @@ impl Client {
649651 let root_dir = fcntl:: open ( & blit_target, OFlag :: O_DIRECTORY | OFlag :: O_RDONLY , Mode :: empty ( ) ) ?;
650652
651653 if let Element :: Directory ( _, _, children) = root {
652- for child in children {
653- self . blit_element ( root_dir , cache_fd , child , & progress , & mut stats ) ? ;
654- }
654+ children
655+ . par_iter ( )
656+ . try_for_each ( |child| self . blit_element ( root_dir , cache_fd , child , & progress , & stats ) ) ? ;
655657 }
656658
657659 close ( root_dir) ?;
@@ -660,7 +662,8 @@ impl Client {
660662 progress. finish_and_clear ( ) ;
661663
662664 let elapsed = now. elapsed ( ) ;
663- let num_entries = stats. num_entries ( ) ;
665+ let stats_raw = stats. write ( ) . unwrap ( ) ;
666+ let num_entries = stats_raw. num_entries ( ) ;
664667
665668 println ! (
666669 "\n {} entries blitted in {} {}" ,
@@ -679,9 +682,9 @@ impl Client {
679682 & self ,
680683 parent : RawFd ,
681684 cache : RawFd ,
682- element : Element < ' _ , PendingFile > ,
685+ element : & Element < ' _ , PendingFile > ,
683686 progress : & ProgressBar ,
684- stats : & mut BlitStats ,
687+ stats : & Arc < RwLock < BlitStats > > ,
685688 ) -> Result < ( ) , Error > {
686689 progress. inc ( 1 ) ;
687690 match element {
@@ -690,10 +693,15 @@ impl Client {
690693 self . blit_element_item ( parent, cache, name, item, stats) ?;
691694
692695 // open the new dir
693- let newdir = fcntl:: openat ( parent, name, OFlag :: O_RDONLY | OFlag :: O_DIRECTORY , Mode :: empty ( ) ) ?;
694- for child in children. into_iter ( ) {
695- self . blit_element ( newdir, cache, child, progress, stats) ?;
696- }
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) ) ?;
697705 close ( newdir) ?;
698706 Ok ( ( ) )
699707 }
@@ -718,7 +726,7 @@ impl Client {
718726 cache : RawFd ,
719727 subpath : & str ,
720728 item : & PendingFile ,
721- stats : & mut BlitStats ,
729+ stats : & Arc < RwLock < BlitStats > > ,
722730 ) -> Result < ( ) , Error > {
723731 match & item. layout . entry {
724732 layout:: Entry :: Regular ( id, _) => {
@@ -764,15 +772,24 @@ impl Client {
764772 }
765773 }
766774
767- stats. num_files += 1 ;
775+ let mut stats_raw = stats. write ( ) . unwrap ( ) ;
776+ {
777+ stats_raw. num_files += 1 ;
778+ }
768779 }
769780 layout:: Entry :: Symlink ( source, _) => {
770781 symlinkat ( source. as_str ( ) , Some ( parent) , subpath) ?;
771- stats. num_symlinks += 1 ;
782+ let mut stats_raw = stats. write ( ) . unwrap ( ) ;
783+ {
784+ stats_raw. num_symlinks += 1 ;
785+ }
772786 }
773787 layout:: Entry :: Directory ( _) => {
774788 mkdirat ( parent, subpath, Mode :: from_bits_truncate ( item. layout . mode ) ) ?;
775- stats. num_dirs += 1 ;
789+ let mut stats_raw = stats. write ( ) . unwrap ( ) ;
790+ {
791+ stats_raw. num_dirs += 1 ;
792+ }
776793 }
777794
778795 // unimplemented
0 commit comments