diff options
author | David Kalnischkies <david@kalnischkies.de> | 2021-03-07 00:47:26 +0100 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2021-03-07 02:55:07 +0100 |
commit | 59933938f51105066161a6eb88253006826336a2 (patch) | |
tree | ff57670a05401c88b071e591d2f539f21bd8209b /apt-pkg | |
parent | 246f66561e23911b9615bd337b3b6f6f25b6cd31 (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.cc | 26 |
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() || |