Skip to content

Commit e52f392

Browse files
joebonrichieermo
authored andcommitted
moss/client: Blit entries in parallel
As children of dirs are pre-structured by vfs, we can blit them all in parallel safely.
1 parent cafd479 commit e52f392

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

moss/src/client/mod.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
};
2930
use postblit::TriggerScope;
31+
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
3032
use stone::{payload::layout, read::PayloadKind};
3133
use thiserror::Error;
3234
use 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

Comments
 (0)