summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2021-03-07 00:47:26 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2021-03-07 02:55:07 +0100
commit59933938f51105066161a6eb88253006826336a2 (patch)
treeff57670a05401c88b071e591d2f539f21bd8209b /apt-pkg
parent246f66561e23911b9615bd337b3b6f6f25b6cd31 (diff)
Start pdiff patching from the last possible starting point
Especially in small sections of an archive it can happen that an index returns to a previous state (e.g. if a package was first added and then removed with no other changes happening in between). The result is that we have multiple patches which start from the same hash which if we perform clientside merging is no problem although not ideal as we perform needless work. For serverside merging it would not matter, but due to rred previously refusing to merge zero-size patches but dak ignoring failure letting it carry these size-zero patches until they naturally expire we run into a problem as these broken patches won't do and force us to fall back to downloading the entire index. By always starting from the last patch instead of the first with the starter hash we can avoid this problem and behave optimally in clientside merge cases, too.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc26
1 files changed, 8 insertions, 18 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 6dc424426..cc3d2f1ff 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -2564,26 +2564,16 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
}
}
-
- bool foundStart = false;
- for (std::vector<DiffInfo>::iterator cur = available_patches.begin();
- cur != available_patches.end(); ++cur)
- {
- if (LocalHashes != cur->result_hashes)
- continue;
-
- available_patches.erase(available_patches.begin(), cur);
- foundStart = true;
- break;
- }
-
- if (foundStart == false || unlikely(available_patches.empty() == true))
{
- ErrorText = "Couldn't find the start of the patch series";
- return false;
- }
+ auto const foundStart = std::find_if(available_patches.rbegin(), available_patches.rend(),
+ [&](auto const &cur) { return LocalHashes == cur.result_hashes; });
+ if (foundStart == available_patches.rend() || unlikely(available_patches.empty()))
+ {
+ ErrorText = "Couldn't find the start of the patch series";
+ return false;
+ }
+ available_patches.erase(available_patches.begin(), std::prev(foundStart.base()));
- {
auto const patch = std::find_if(available_patches.cbegin(), available_patches.cend(), [](auto const &patch) {
return not patch.result_hashes.usable() ||
not patch.patch_hashes.usable() ||