# # patch "ChangeLog" # from [30223bcaf7c5f9aadcc2b006eee62a8dd63fe2f5] # to [098f931c622ef79fe7cc8f389d4851fe9599541f] # # patch "file_io.cc" # from [6125dbcc50e69e63ba8a22664e3e8126ee1115a0] # to [ff47ce57304e48a07f9e6c539610f7d992c5e773] # # patch "transforms.cc" # from [a84ed105809f55ba4097a4559ecc53ec21f9ab17] # to [041db043a6e340a55705de868e77a0fad8b5a413] # # patch "transforms.hh" # from [a6b73afd42a8ffa3ff52368cc3b5c7b8e445b713] # to [beb9c11a04e735f442928aea2e984834c8573c8d] # # patch "vocab.hh" # from [77bb3d7df9abc7e4e5202cb20b313c925dad2c13] # to [e7d7947fe544166a511b44911cff89fa62ace2e9] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,10 @@ +2005-06-24 Matt Johnston + + * transforms.{cc,hh}: combine gzip and base64 in one + pipe for pack()/unpack() to save memory + * vocab.hh: add swap() to encodings/atomics + * file_io.cc: use swap() to avoid copying + 2005-06-21 Nathaniel Smith * commands.cc (do_diff): Use calculate_arbitrary_change_set, --- file_io.cc +++ file_io.cc @@ -384,7 +384,7 @@ if (!file) throw oops(string("cannot open file ") + p.string() + " for reading"); CryptoPP::FileSource f(file, true, new CryptoPP::StringSink(in)); - dat = in; + dat.swap(in); } // This function can only be called once per run. @@ -396,7 +396,7 @@ have_consumed_stdin = true; string in; CryptoPP::FileSource f(cin, true, new CryptoPP::StringSink(in)); - dat = in; + dat.swap(in); } void @@ -461,7 +461,7 @@ read_data(path, tdat); string tmp1, tmp2; - tmp2 = tdat(); + tdat.swap(tmp2); if (do_charconv) { tmp1 = tmp2; charset_convert(ext_charset, db_charset, tmp1, tmp2); @@ -470,7 +470,7 @@ tmp1 = tmp2; line_end_convert(db_linesep, tmp1, tmp2); } - dat = tmp2; + dat.swap(tmp2); } --- transforms.cc +++ transforms.cc @@ -157,10 +157,43 @@ return n; } +template +void pack(T const & in, base64< gzip > & out) +{ + string tmp; + tmp.reserve(in().size()); // FIXME: do some benchmarking and make this a constant:: -// diffing and patching + CryptoPP::StringSource + str(in(), true, + new CryptoPP::Gzip( + new CryptoPP::Base64Encoder( + new CryptoPP::StringSink(tmp)))); + out.swap(tmp); +} +template +void unpack(base64< gzip > const & in, T & out) +{ + string tmp; + tmp.reserve(in().size()); // FIXME: do some benchmarking and make this a constant:: + CryptoPP::StringSource + str(in(), true, + new CryptoPP::Base64Decoder( + new CryptoPP::Gunzip( + new CryptoPP::StringSink(tmp)))); + + out.swap(tmp); +} + +// specialise them +template void pack(data const &, base64< gzip > &); +template void pack(delta const &, base64< gzip > &); +template void unpack(base64< gzip > const &, data &); +template void unpack(base64< gzip > const &, delta &); + +// diffing and patching + void diff(data const & olddata, data const & newdata, --- transforms.hh +++ transforms.hh @@ -77,20 +77,14 @@ // both at once (this is relatively common) template -void pack(T const & in, base64< gzip > & out) -{ - gzip tmp; - encode_gzip(in, tmp); - encode_base64(tmp, out); -} +void pack(T const & in, base64< gzip > & out); +extern template void pack(data const &, base64< gzip > &); +extern template void pack(delta const &, base64< gzip > &); template -void unpack(base64< gzip > const & in, T & out) -{ - gzip tmp; - decode_base64(in, tmp); - decode_gzip(tmp, out); -} +void unpack(base64< gzip > const & in, T & out); +extern template void unpack(base64< gzip > const &, data &); +extern template void unpack(base64< gzip > const &, delta &); // diffing and patching --- vocab.hh +++ vocab.hh @@ -33,6 +33,8 @@ enc(std::string const & s); \ enc(INNER const & inner); \ enc(enc const & other); \ + void swap(std::string & str) \ + { i.swap(str); } \ std::string const & operator()() const \ { return i(); } \ bool operator<(enc const & x) const \ @@ -86,6 +88,8 @@ ty(ty const & other); \ std::string const & operator()() const \ { return s; } \ + void swap(std::string & str) \ + { s.swap(str); } \ bool operator<(ty const & other) const \ { return s < other(); } \ ty const & operator=(ty const & other); \