Skip to content

Commit

Permalink
moss/client: Blit entries in parallel
Browse files Browse the repository at this point in the history
As children of dirs are pre-structured by vfs, we can blit them all
in parallel safely.
  • Loading branch information
joebonrichie committed Feb 25, 2025
1 parent 5e85a62 commit 12f0388
Showing 1 changed file with 33 additions and 16 deletions.
49 changes: 33 additions & 16 deletions moss/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{
fmt, io,
os::{fd::RawFd, unix::fs::symlink},
path::{Path, PathBuf},
sync::{Arc, RwLock},
time::{Duration, Instant},
};

Expand All @@ -26,6 +27,7 @@ use nix::{
unistd::{close, linkat, mkdir, symlinkat},
};
use postblit::TriggerScope;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use stone::{payload::layout, read::PayloadKind};
use thiserror::Error;
use tui::{MultiProgress, ProgressBar, ProgressStyle, Styled};
Expand Down Expand Up @@ -625,7 +627,7 @@ impl Client {
progress.tick();

let now = Instant::now();
let mut stats = BlitStats::default();
let stats = Arc::new(RwLock::new(BlitStats::default()));

let tree = self.vfs(packages)?;

Expand All @@ -648,9 +650,9 @@ impl Client {
let root_dir = fcntl::open(&blit_target, OFlag::O_DIRECTORY | OFlag::O_RDONLY, Mode::empty())?;

if let Element::Directory(_, _, children) = root {
for child in children {
self.blit_element(root_dir, cache_fd, child, &progress, &mut stats)?;
}
children
.par_iter()
.try_for_each(|child| self.blit_element(root_dir, cache_fd, child, &progress, &stats))?;
}

close(root_dir)?;
Expand All @@ -659,7 +661,8 @@ impl Client {
progress.finish_and_clear();

let elapsed = now.elapsed();
let num_entries = stats.num_entries();
let stats_raw = stats.write().unwrap();
let num_entries = stats_raw.num_entries();

println!(
"\n{} entries blitted in {} {}",
Expand All @@ -678,9 +681,9 @@ impl Client {
&self,
parent: RawFd,
cache: RawFd,
element: Element<'_, PendingFile>,
element: &Element<'_, PendingFile>,
progress: &ProgressBar,
stats: &mut BlitStats,
stats: &Arc<RwLock<BlitStats>>,
) -> Result<(), Error> {
progress.inc(1);
match element {
Expand All @@ -689,10 +692,15 @@ impl Client {
self.blit_element_item(parent, cache, name, item, stats)?;

// open the new dir
let newdir = fcntl::openat(parent, name, OFlag::O_RDONLY | OFlag::O_DIRECTORY, Mode::empty())?;
for child in children.into_iter() {
self.blit_element(newdir, cache, child, progress, stats)?;
}
let newdir = fcntl::openat(
parent,
name.to_owned(),
OFlag::O_RDONLY | OFlag::O_DIRECTORY,
Mode::empty(),
)?;
children
.par_iter()
.try_for_each(|child| self.blit_element(newdir, cache, child, progress, stats))?;
close(newdir)?;
Ok(())
}
Expand All @@ -717,7 +725,7 @@ impl Client {
cache: RawFd,
subpath: &str,
item: &PendingFile,
stats: &mut BlitStats,
stats: &Arc<RwLock<BlitStats>>,
) -> Result<(), Error> {
match &item.layout.entry {
layout::Entry::Regular(id, _) => {
Expand Down Expand Up @@ -763,15 +771,24 @@ impl Client {
}
}

stats.num_files += 1;
let mut stats_raw = stats.write().unwrap();
{
stats_raw.num_files += 1;
}
}
layout::Entry::Symlink(source, _) => {
symlinkat(source.as_str(), Some(parent), subpath)?;
stats.num_symlinks += 1;
let mut stats_raw = stats.write().unwrap();
{
stats_raw.num_symlinks += 1;
}
}
layout::Entry::Directory(_) => {
mkdirat(parent, subpath, Mode::from_bits_truncate(item.layout.mode))?;
stats.num_dirs += 1;
let mut stats_raw = stats.write().unwrap();
{
stats_raw.num_dirs += 1;
}
}

// unimplemented
Expand Down Expand Up @@ -975,7 +992,7 @@ struct BlitStats {
num_dirs: u64,
}

impl BlitStats {
impl<'a> BlitStats {

Check warning on line 995 in moss/src/client/mod.rs

View workflow job for this annotation

GitHub Actions / Build & Test Project

[clippy] reported by reviewdog 🐶 warning: this lifetime isn't used in the impl --> moss/src/client/mod.rs:995:6 | 995 | impl<'a> BlitStats { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes = note: `#[warn(clippy::extra_unused_lifetimes)]` on by default Raw Output: moss/src/client/mod.rs:995:6:w:warning: this lifetime isn't used in the impl --> moss/src/client/mod.rs:995:6 | 995 | impl<'a> BlitStats { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes = note: `#[warn(clippy::extra_unused_lifetimes)]` on by default __END__
fn num_entries(&self) -> u64 {
self.num_files + self.num_symlinks + self.num_dirs
}
Expand Down

0 comments on commit 12f0388

Please sign in to comment.