format/payload: Remove unnecessary function pointer in extract_images()

The list of output files that are needed are known beforehand. There's
no need to dynamically open them.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit is contained in:
Andrew Gunnerson
2025-08-23 18:47:05 -04:00
parent ab51654dad
commit 8bb1f771af
2 changed files with 17 additions and 18 deletions
+7 -3
View File
@@ -53,7 +53,7 @@ use crate::{
},
stream::{
self, FromReader, HashingWriter, MutexFile, ReadAt, SectionReader, SectionReaderAt,
ToWriter, UserPosFile,
ToWriter, UserPosFile, WriteAt,
},
util,
};
@@ -1344,9 +1344,13 @@ pub fn extract_payload(
// Extract the images.
payload::extract_images(
&payload_reader,
|name| Ok(Box::new(output_files[name].clone())),
images.iter().map(|n| {
(
n.as_str(),
&output_files[n.as_str()] as &(dyn WriteAt + Sync),
)
}),
header,
images.iter().map(|n| n.as_str()),
cancel_signal,
)
.context("Failed to extract images from payload")?;
+10 -15
View File
@@ -126,10 +126,8 @@ pub enum Error {
num_blocks: u64,
source: io::Error,
},
#[error("Failed to open input file for partition: {0}")]
InputOpen(String, #[source] io::Error),
#[error("Failed to open output file for partition: {0}")]
OutputOpen(String, #[source] io::Error),
#[error("Failed to get input file size for partition: {0}")]
InputSize(String, #[source] io::Error),
#[error("Failed to GZ compress partition image chunk")]
GzCompress(#[source] io::Error),
#[error("Failed to initialize XZ encoder")]
@@ -870,16 +868,15 @@ pub fn extract_image(
}
/// Extract the specified partition images from the payload into writers. This
/// is done multithreaded and uses rayon's global thread pool. `open_output`
/// will be called from multiple threads.
pub fn extract_images<'a>(
/// is done multithreaded and uses rayon's global thread pool.
pub fn extract_images<'name, 'file>(
payload: &(dyn ReadAt + Sync),
open_output: impl Fn(&str) -> io::Result<Box<dyn WriteAt>> + Sync,
outputs: impl IntoIterator<Item = (&'name str, &'file (dyn WriteAt + Sync))>,
header: &PayloadHeader,
partition_names: impl IntoIterator<Item = &'a str>,
cancel_signal: &AtomicBool,
) -> Result<()> {
let mut remaining = partition_names.into_iter().collect::<HashSet<_>>();
let outputs = outputs.into_iter().collect::<HashMap<_, _>>();
let mut remaining = outputs.keys().copied().collect::<HashSet<_>>();
// We parallelize at the operation level or else one thread might get stuck
// processing a giant image.
let mut operations = vec![];
@@ -901,9 +898,7 @@ pub fn extract_images<'a>(
.into_par_iter()
.try_for_each(|(name, op)| -> Result<()> {
let mut reader = UserPosFile::new(payload);
let mut writer = open_output(name)
.map(UserPosFile::new)
.map_err(|e| Error::OutputOpen(name.to_owned(), e))?;
let mut writer = UserPosFile::new(&outputs[name]);
apply_operation(
&mut reader,
@@ -1265,7 +1260,7 @@ pub fn compute_cow_estimate(
) -> Result<CowEstimate> {
let file_size = input
.file_len()
.map_err(|e| Error::InputOpen(partition_name.to_owned(), e))?;
.map_err(|e| Error::InputSize(partition_name.to_owned(), e))?;
let final_chunk_different = file_size % CHUNK_SIZE != 0;
validate_partition_size(
@@ -1349,7 +1344,7 @@ pub fn compress_image(
let file_size = input
.file_len()
.map_err(|e| Error::InputOpen(partition_name.to_owned(), e))?;
.map_err(|e| Error::InputSize(partition_name.to_owned(), e))?;
let final_chunk_different = file_size % CHUNK_SIZE != 0;
let compression_factor = vabc_params.map_or(block_size, |p| p.compression_factor);