diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-01-24 17:41:00 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-01-24 17:41:00 +0000 |
| commit | 59e769023c392c332331567a1aea94660002c463 (patch) | |
| tree | e68d918e3c48f470a688b8bb5bf95590fb9c4916 /src/lib/util.cc | |
| parent | 5af65f61bf6eba06c24025d63b43aec896a00c9c (diff) | |
Hand-apply bbfb370d7de28ec1e8f307865cc6253bb5d4366e from master; quicker digest calculation.
Diffstat (limited to 'src/lib/util.cc')
| -rw-r--r-- | src/lib/util.cc | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/src/lib/util.cc b/src/lib/util.cc index c0e32b778..0a6f381db 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -417,45 +417,53 @@ dcpomatic_setup_gettext_i18n (string lang) #endif } -/** @param job Optional job for which to report progress */ +/** Compute a digest of the first and last `size' bytes of a set of files. */ string -md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job) +md5_digest_head_tail (vector<boost::filesystem::path> files, boost::uintmax_t size) { - boost::uintmax_t const buffer_size = 64 * 1024; - char buffer[buffer_size]; - + boost::scoped_array<char> buffer (new char[size]); MD5Digester digester; - vector<int64_t> sizes; - for (size_t i = 0; i < files.size(); ++i) { - sizes.push_back (boost::filesystem::file_size (files[i])); - } - - for (size_t i = 0; i < files.size(); ++i) { + /* Head */ + boost::uintmax_t to_do = size; + char* p = buffer.get (); + int i = 0; + while (i < int64_t (files.size()) && to_do > 0) { FILE* f = fopen_boost (files[i], "rb"); if (!f) { throw OpenFileError (files[i].string()); } - boost::uintmax_t const bytes = boost::filesystem::file_size (files[i]); - boost::uintmax_t remaining = bytes; - - while (remaining > 0) { - int const t = min (remaining, buffer_size); - int const r = fread (buffer, 1, t, f); - if (r != t) { - throw ReadFileError (files[i], errno); - } - digester.add (buffer, t); - remaining -= t; - - if (job) { - job->set_progress ((float (i) + 1 - float(remaining) / bytes) / files.size ()); - } + boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i])); + fread (p, 1, this_time, f); + p += this_time; + to_do -= this_time; + fclose (f); + + ++i; + } + digester.add (buffer.get(), size - to_do); + + /* Tail */ + to_do = size; + p = buffer.get (); + i = files.size() - 1; + while (i >= 0 && to_do > 0) { + FILE* f = fopen_boost (files[i], "rb"); + if (!f) { + throw OpenFileError (files[i].string()); } + boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i])); + fseek (f, -this_time, SEEK_END); + fread (p, 1, this_time, f); + p += this_time; + to_do -= this_time; fclose (f); - } + + --i; + } + digester.add (buffer.get(), size - to_do); return digester.get (); } |
