summaryrefslogtreecommitdiffstats
path: root/courgette/ensemble_apply.cc
diff options
context:
space:
mode:
authorsra@chromium.org <sra@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-23 21:18:48 +0000
committersra@chromium.org <sra@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-23 21:18:48 +0000
commit6db3cd4ebccf65c9bbe1bb6d6239ec103caaf518 (patch)
treec2ab9d415c80ae62ff06fdbb8be3472271daacb0 /courgette/ensemble_apply.cc
parentce910b9d066453ea491473c4ef9e73b163a58d6d (diff)
downloadchromium_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/ensemble_apply.cc')
-rw-r--r--courgette/ensemble_apply.cc21
1 files changed, 20 insertions, 1 deletions
diff --git a/courgette/ensemble_apply.cc b/courgette/ensemble_apply.cc
index d1310b4..0785598 100644
--- a/courgette/ensemble_apply.cc
+++ b/courgette/ensemble_apply.cc
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/file_util.h"
+#include "base/logging.h"
#include "courgette/crc.h"
#include "courgette/image_info.h"
@@ -63,6 +64,7 @@ class EnsemblePatchApplication {
uint32 source_checksum_;
uint32 target_checksum_;
+ uint32 final_patch_input_size_prediction_;
std::vector<TransformationPatcher*> patchers_;
@@ -73,7 +75,8 @@ class EnsemblePatchApplication {
};
EnsemblePatchApplication::EnsemblePatchApplication()
- : source_checksum_(0), target_checksum_(0) {
+ : source_checksum_(0), target_checksum_(0),
+ final_patch_input_size_prediction_(0) {
}
EnsemblePatchApplication::~EnsemblePatchApplication() {
@@ -103,6 +106,9 @@ Status EnsemblePatchApplication::ReadHeader(SourceStream* header_stream) {
if (!header_stream->ReadVarint32(&target_checksum_))
return C_BAD_ENSEMBLE_HEADER;
+ if (!header_stream->ReadVarint32(&final_patch_input_size_prediction_))
+ return C_BAD_ENSEMBLE_HEADER;
+
return C_OK;
}
@@ -214,6 +220,8 @@ Status EnsemblePatchApplication::TransformDown(
SinkStream* basic_elements) {
// Construct blob of original input followed by reformed elements.
+ basic_elements->Reserve(final_patch_input_size_prediction_);
+
// The original input:
basic_elements->Write(base_region_.start(), base_region_.length());
@@ -231,6 +239,9 @@ Status EnsemblePatchApplication::TransformDown(
if (!transformed_elements->Empty())
return C_STREAM_NOT_CONSUMED;
+ // We have totally consumed transformed_elements, so can free the
+ // storage to which it referred.
+ corrected_elements_storage_.Retire();
return C_OK;
}
@@ -374,13 +385,21 @@ Status ApplyEnsemblePatch(const FilePath::CharType* old_file_name,
return status;
// Header smells good so read the whole patch file for real.
+ int64 patch_file_size = 0;
+ if (!file_util::GetFileSize(patch_file_path, &patch_file_size))
+ return C_READ_ERROR;
std::string patch_file_buffer;
+ patch_file_buffer.reserve(static_cast<size_t>(patch_file_size));
if (!file_util::ReadFileToString(patch_file_path, &patch_file_buffer))
return C_READ_ERROR;
// Read the old_file.
FilePath old_file_path(old_file_name);
+ int64 old_file_size = 0;
+ if (!file_util::GetFileSize(old_file_path, &old_file_size))
+ return C_READ_ERROR;
std::string old_file_buffer;
+ old_file_buffer.reserve(static_cast<size_t>(old_file_size));
if (!file_util::ReadFileToString(old_file_path, &old_file_buffer))
return C_READ_ERROR;