diff options
author | sra@chromium.org <sra@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 21:18:48 +0000 |
---|---|---|
committer | sra@chromium.org <sra@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 21:18:48 +0000 |
commit | 6db3cd4ebccf65c9bbe1bb6d6239ec103caaf518 (patch) | |
tree | c2ab9d415c80ae62ff06fdbb8be3472271daacb0 /courgette/courgette_tool.cc | |
parent | ce910b9d066453ea491473c4ef9e73b163a58d6d (diff) | |
download | chromium_src-6db3cd4ebccf65c9bbe1bb6d6239ec103caaf518.zip chromium_src-6db3cd4ebccf65c9bbe1bb6d6239ec103caaf518.tar.gz chromium_src-6db3cd4ebccf65c9bbe1bb6d6239ec103caaf518.tar.bz2 |
Improved memory usage while applying patch.
Reduced total size of allocations from 520MB to 318MB.
The general technique is to allocate the correct size rather than grow into
the correct size and overshoot.
1. Find file sizes and allocate buffers of that size for the input files.
2. Pre-allocate a buffer for the collected inputs for the final diff.
3. Calculate the size for (2) during compression and include it in the patch
header.
The courgette.exe command line tool now calls the same ApplyEnsemblePatch
entry point that is called by the installer. This ensures measurements of
courgette.exe are a better reflection of the installer.
BUG=72459
Review URL: http://codereview.chromium.org/6546008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75787 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'courgette/courgette_tool.cc')
-rw-r--r-- | courgette/courgette_tool.cc | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/courgette/courgette_tool.cc b/courgette/courgette_tool.cc index 7176442..523a438 100644 --- a/courgette/courgette_tool.cc +++ b/courgette/courgette_tool.cc @@ -52,7 +52,11 @@ std::string ReadOrFail(const std::wstring& file_name, const char* kind) { #else FilePath file_path(WideToASCII(file_name)); #endif + int64 file_size = 0; + if (!file_util::GetFileSize(file_path, &file_size)) + Problem("Can't read %s file.", kind); std::string buffer; + buffer.reserve(static_cast<size_t>(file_size)); if (!file_util::ReadFileToString(file_path, &buffer)) Problem("Can't read %s file.", kind); return buffer; @@ -285,20 +289,48 @@ void GenerateEnsemblePatch(const std::wstring& old_file, void ApplyEnsemblePatch(const std::wstring& old_file, const std::wstring& patch_file, const std::wstring& new_file) { - std::string old_buffer = ReadOrFail(old_file, "'old' input"); - std::string patch_buffer = ReadOrFail(patch_file, "'patch' input"); + // We do things a little differently here in order to call the same Courgette + // entry point as the installer. That entry point point takes file names and + // returns an status code but does not output any diagnostics. +#if defined(OS_WIN) + FilePath old_path(old_file); + FilePath patch_path(patch_file); + FilePath new_path(new_file); +#else + FilePath old_path(WideToASCII(old_file)); + FilePath patch_path(WideToASCII(patch_file)); + FilePath new_path(WideToASCII(new_file)); +#endif - courgette::SourceStream old_stream; - courgette::SourceStream patch_stream; - old_stream.Init(old_buffer); - patch_stream.Init(patch_buffer); - courgette::SinkStream new_stream; courgette::Status status = - courgette::ApplyEnsemblePatch(&old_stream, &patch_stream, &new_stream); + courgette::ApplyEnsemblePatch(old_path.value().c_str(), + patch_path.value().c_str(), + new_path.value().c_str()); + + if (status == courgette::C_OK) + return; + + // Diagnose the error. + if (status == courgette::C_BAD_ENSEMBLE_MAGIC) + Problem("Not a courgette patch"); + if (status == courgette::C_BAD_ENSEMBLE_VERSION) + Problem("Wrong version patch"); + if (status == courgette::C_BAD_ENSEMBLE_HEADER) + Problem("Corrupt patch"); + // If we failed due to a missing input file, this will + // print the message. + std::string old_buffer = ReadOrFail(old_file, "'old' input"); + old_buffer.clear(); + std::string patch_buffer = ReadOrFail(patch_file, "'patch' input"); + patch_buffer.clear(); - if (status != courgette::C_OK) Problem("-apply failed."); + // Non-input related errors: + if (status == courgette::C_WRITE_OPEN_ERROR) + Problem("Can't open output"); + if (status == courgette::C_WRITE_ERROR) + Problem("Can't write output"); - WriteSinkToFile(&new_stream, new_file); + Problem("-apply failed."); } void GenerateBSDiffPatch(const std::wstring& old_file, |