Sort FileDeltaProcessor.
Put the files with more new blocks (takes longer) first, because with
enough cores, most of the time we are just waiting for a few large
files to complete.
Changed vector to list in order to sort class with const member.
Bug: 77817425
Test: generated a delta payload
Change-Id: I92088b69350776e2a509094df3413104bea18fa7
diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc
index bb98c62..5329dbf 100644
--- a/payload_generator/delta_diff_utils.cc
+++ b/payload_generator/delta_diff_utils.cc
@@ -29,6 +29,8 @@
#include <unistd.h>
#include <algorithm>
+#include <functional>
+#include <list>
#include <map>
#include <memory>
#include <utility>
@@ -55,6 +57,7 @@
#include "update_engine/payload_generator/squashfs_filesystem.h"
#include "update_engine/payload_generator/xz.h"
+using std::list;
using std::map;
using std::string;
using std::vector;
@@ -195,13 +198,16 @@
version_(version),
old_extents_(old_extents),
new_extents_(new_extents),
+ new_extents_blocks_(utils::BlocksInExtents(new_extents)),
old_deflates_(old_deflates),
new_deflates_(new_deflates),
name_(name),
chunk_blocks_(chunk_blocks),
blob_file_(blob_file) {}
- FileDeltaProcessor(FileDeltaProcessor&& processor) = default;
+ bool operator>(const FileDeltaProcessor& other) const {
+ return new_extents_blocks_ > other.new_extents_blocks_;
+ }
~FileDeltaProcessor() override = default;
@@ -221,11 +227,12 @@
// The block ranges of the old/new file within the src/tgt image
const vector<Extent> old_extents_;
const vector<Extent> new_extents_;
+ const size_t new_extents_blocks_;
const vector<puffin::BitExtent> old_deflates_;
const vector<puffin::BitExtent> new_deflates_;
const string name_;
// Block limit of one aop.
- ssize_t chunk_blocks_;
+ const ssize_t chunk_blocks_;
BlobFileWriter* blob_file_;
// The list of ops to reach the new file from the old file.
@@ -237,8 +244,8 @@
void FileDeltaProcessor::Run() {
TEST_AND_RETURN(blob_file_ != nullptr);
- LOG(INFO) << "Encoding file " << name_ << " ("
- << utils::BlocksInExtents(new_extents_) << " blocks)";
+ LOG(INFO) << "Encoding file " << name_ << " (" << new_extents_blocks_
+ << " blocks)";
if (!DeltaReadFile(&file_aops_,
old_part_,
@@ -252,7 +259,7 @@
version_,
blob_file_)) {
LOG(ERROR) << "Failed to generate delta for " << name_ << " ("
- << utils::BlocksInExtents(new_extents_) << " blocks)";
+ << new_extents_blocks_ << " blocks)";
}
}
@@ -298,7 +305,7 @@
TEST_AND_RETURN_FALSE(deflate_utils::PreprocessParitionFiles(
new_part, &new_files, puffdiff_allowed));
- vector<FileDeltaProcessor> file_delta_processors;
+ list<FileDeltaProcessor> file_delta_processors;
// The processing is very straightforward here, we generate operations for
// every file (and pseudo-file such as the metadata) in the new filesystem
@@ -375,6 +382,13 @@
}
size_t max_threads = GetMaxThreads();
+
+ // Sort the files in descending order based on number of new blocks to make
+ // sure we start the largest ones first.
+ if (file_delta_processors.size() > max_threads) {
+ file_delta_processors.sort(std::greater<FileDeltaProcessor>());
+ }
+
base::DelegateSimpleThreadPool thread_pool("incremental-update-generator",
max_threads);
thread_pool.Start();