diff options
author | David Kalnischkies <david@kalnischkies.de> | 2016-01-08 15:30:05 +0100 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2016-01-08 15:40:01 +0100 |
commit | 4e6219da0dd1e68fad7db972f7ddd76598645228 (patch) | |
tree | 6a2914e6d426069038dd4407abdedd8faacc7ba1 /apt-pkg | |
parent | 896f0ae857b693782658145e16e21a3054dd5280 (diff) |
use filesize of compressed pdiffs for the limit if possible
With the addition of the $HASH-Download field in the .diff/Index we got
the size of the compressed patches for 'free', so if that information is
available we can use it for a more fitting calculation of the size
requirements of the patches vs. the complete file.
Note that this predicts a too small size in the transition case in which
the information isn't available for all patches, but figuring this out
would be a lot of code for practically nothing as only one update can
ever be in such a transition phase.
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/acquire-item.cc | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 7c7a204c4..b73c4985f 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -2032,18 +2032,55 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ } // calculate the size of all patches we have to get - // note that all sizes are uncompressed, while we download compressed files - unsigned long long patchesSize = 0; - for (std::vector<DiffInfo>::const_iterator cur = available_patches.begin(); - cur != available_patches.end(); ++cur) - patchesSize += cur->patch_hashes.FileSize(); - unsigned long long const sizeLimit = ServerSize * _config->FindI("Acquire::PDiffs::SizeLimit", 100); - if (sizeLimit > 0 && (sizeLimit/100) < patchesSize) - { - if (Debug) - std::clog << "Need " << patchesSize << " bytes (Limit is " << sizeLimit/100 - << ") so fallback to complete download" << std::endl; - return false; + unsigned short const sizeLimitPercent = _config->FindI("Acquire::PDiffs::SizeLimit", 100); + if (sizeLimitPercent > 0 && TransactionManager->MetaIndexParser != nullptr) + { + // compressed case + unsigned long long downloadSize = std::accumulate(available_patches.begin(), + available_patches.end(), 0llu, [](unsigned long long const T, DiffInfo const &I) { + return T + I.download_hashes.FileSize(); + }); + if (downloadSize != 0) + { + unsigned long long downloadSizeIdx = 0; + auto const types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' '); + for (auto const &t : types) + { + std::string MetaKey = Target.MetaKey; + if (t != "uncompressed") + MetaKey += '.' + t; + HashStringList const hsl = GetExpectedHashesFor(MetaKey); + if (unlikely(hsl.usable() == false)) + continue; + downloadSizeIdx = hsl.FileSize(); + break; + } + unsigned long long const sizeLimit = downloadSizeIdx * sizeLimitPercent; + if ((sizeLimit/100) < downloadSize) + { + if (Debug) + std::clog << "Need " << downloadSize << " compressed bytes (Limit is " << (sizeLimit/100) << ", " + << "original is " << downloadSizeIdx << ") so fallback to complete download" << std::endl; + return false; + } + } + // uncompressed case + downloadSize = std::accumulate(available_patches.begin(), + available_patches.end(), 0llu, [](unsigned long long const T, DiffInfo const &I) { + return T + I.patch_hashes.FileSize(); + }); + if (downloadSize != 0) + { + unsigned long long const downloadSizeIdx = ServerSize; + unsigned long long const sizeLimit = downloadSizeIdx * sizeLimitPercent; + if ((sizeLimit/100) < downloadSize) + { + if (Debug) + std::clog << "Need " << downloadSize << " uncompressed bytes (Limit is " << (sizeLimit/100) << ", " + << "original is " << downloadSizeIdx << ") so fallback to complete download" << std::endl; + return false; + } + } } // we have something, queue the diffs |