diff options
author | Marc Laukien <marc@zeroc.com> | 2004-12-01 21:54:37 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2004-12-01 21:54:37 +0000 |
commit | fdc996e64dae22ee7752135821dd43bd4ac0813a (patch) | |
tree | db3ef636550a87db6c3e3b1654297b33c0120e94 /cpp | |
parent | fixes (diff) | |
download | ice-fdc996e64dae22ee7752135821dd43bd4ac0813a.tar.bz2 ice-fdc996e64dae22ee7752135821dd43bd4ac0813a.tar.xz ice-fdc996e64dae22ee7752135821dd43bd4ac0813a.zip |
fixes
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 19 | ||||
-rwxr-xr-x | cpp/src/IcePatch2/ClientUtil.cpp | 509 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Util.cpp | 66 |
3 files changed, 355 insertions, 239 deletions
diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index 7d066a94672..a121fb727dd 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -204,10 +204,6 @@ IcePatch2::Client::run(int argc, char* argv[]) { properties->setProperty("IcePatch2.Thorough", "1"); } - else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dry") == 0) - { - properties->setProperty("IcePatch2.DryRun", "1"); - } else if(argv[i][0] == '-') { cerr << argv[0] << ": unknown option `" << argv[i] << "'" << endl; @@ -248,7 +244,17 @@ IcePatch2::Client::run(int argc, char* argv[]) if(!aborted) { - aborted = !patcher->patch(); + aborted = !patcher->patch("Ice"); + } + + if(!aborted) + { + aborted = !patcher->patch(""); + } + + if(!aborted) + { + patcher->finish(); } } catch(const string& ex) @@ -275,8 +281,7 @@ IcePatch2::Client::usage(const string& appName) "Options:\n" "-h, --help Show this message.\n" "-v, --version Display the Ice version.\n" - "-t, --thorough Recalculate all checksums.\n" - "-d, --dry Don't update, do a dry run only."; + "-t, --thorough Recalculate all checksums."; cerr << "Usage: " << appName << " [options] [DIR]" << endl; cerr << options << endl; diff --git a/cpp/src/IcePatch2/ClientUtil.cpp b/cpp/src/IcePatch2/ClientUtil.cpp index 45962862b7d..754f7758874 100755 --- a/cpp/src/IcePatch2/ClientUtil.cpp +++ b/cpp/src/IcePatch2/ClientUtil.cpp @@ -10,6 +10,7 @@ #include <IcePatch2/ClientUtil.h> #include <IcePatch2/Util.h> #include <IcePatch2/FileServerI.h> +#include <list> #ifdef _WIN32 # include <direct.h> @@ -19,13 +20,131 @@ using namespace std; using namespace Ice; using namespace IcePatch2; +namespace IcePatch2 +{ + +class Decompressor : public IceUtil::Thread, IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + Decompressor(const string& dataDir) : + _dataDir(dataDir), + _destroy(false) + { + } + + virtual ~Decompressor() + { + assert(_destroy); + } + + void + destroy() + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _destroy = true; + notify(); + } + + void + add(const FileInfo info) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(!_exception.empty()) + { + throw _exception; + } + _files.push_back(info); + notify(); + } + + void + exception() const + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(!_exception.empty()) + { + throw _exception; + } + } + + void + log(ofstream& os) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + for(FileInfoSeq::const_iterator p = _filesDone.begin(); p != _filesDone.end(); ++p) + { + os << '+' << *p << endl; + } + + _filesDone.clear(); + } + + virtual void + run() + { + FileInfo info; + + while(true) + { + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + if(!info.path.empty()) + { + _filesDone.push_back(info); + } + + while(!_destroy && _files.empty()) + { + wait(); + } + + if(!_files.empty()) + { + info = _files.front(); + _files.pop_front(); + } + else + { + return; + } + } + + try + { + decompressFile(_dataDir + '/' + info.path); + remove(_dataDir + '/' + info.path + ".bz2"); + } + catch(const string& ex) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _destroy = true; + _exception = ex; + return; + } + } + } + +private: + + const string _dataDir; + + string _exception; + list<FileInfo> _files; + FileInfoSeq _filesDone; + + bool _destroy; +}; + +} + IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) : _feedback(feedback), _dataDir(normalize(communicator->getProperties()->getProperty("IcePatch2.Directory"))), _thorough(communicator->getProperties()->getPropertyAsInt("IcePatch2.Thorough") > 0), - _dryRun(communicator->getProperties()->getPropertyAsInt("IcePatch2.DryRun") > 0), - _chunkSize(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100000)), - _decompress(false) + _chunkSize(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100000)) { if(_dataDir.empty()) { @@ -73,7 +192,6 @@ IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFe IcePatch2::Patcher::~Patcher() { - assert(!_decompress); } bool @@ -160,74 +278,144 @@ IcePatch2::Patcher::prepare() sort(_removeFiles.begin(), _removeFiles.end(), FileInfoLess()); sort(_updateFiles.begin(), _updateFiles.end(), FileInfoLess()); + string pathLog = _dataDir + ".log"; + _log.open(pathLog.c_str()); + if(!_log) + { + throw "cannot open `" + pathLog + "' for writing: " + lastError(); + } + return true; } bool -IcePatch2::Patcher::patch() +IcePatch2::Patcher::patch(const string& d) { - if(!_removeFiles.empty()) + string dir = normalize(d); + + if(dir.empty() || dir == ".") { - if(!removeFiles(_removeFiles)) + if(!_removeFiles.empty()) { - return false; + if(!removeFiles(_removeFiles)) + { + return false; + } } - if(!_dryRun) + if(!_updateFiles.empty()) { - saveFileInfoSeq(_dataDir, _localFiles); + if(!updateFiles(_updateFiles)) + { + return false; + } } + + return true; } - - if(!_updateFiles.empty()) + else { - if(!updateFiles(_updateFiles)) + string dirWithSlash = dir + '/'; + + FileInfoSeq::const_iterator p; + + FileInfoSeq remove; + for(p = _removeFiles.begin(); p != _removeFiles.end(); ++p) { - return false; + if(p->size < 0) // Directory? + { + if(p->path.compare(0, dir.size(), dir) == 0) + { + remove.push_back(*p); + } + } + else + { + if(p->path.compare(0, dirWithSlash.size(), dirWithSlash) == 0) + { + remove.push_back(*p); + } + } + } + + FileInfoSeq update; + for(p = _updateFiles.begin(); p != _updateFiles.end(); ++p) + { + if(p->size < 0) // Directory? + { + if(p->path.compare(0, dir.size(), dir) == 0) + { + update.push_back(*p); + } + } + else + { + if(p->path.compare(0, dirWithSlash.size(), dirWithSlash) == 0) + { + update.push_back(*p); + } + } + } + + if(!remove.empty()) + { + if(!removeFiles(remove)) + { + return false; + } } - if(!_dryRun) + if(!update.empty()) { - saveFileInfoSeq(_dataDir, _localFiles); + if(!updateFiles(update)) + { + return false; + } } + + return true; } +} - return true; +void +IcePatch2::Patcher::finish() +{ + _log.close(); + + saveFileInfoSeq(_dataDir, _localFiles); } bool IcePatch2::Patcher::removeFiles(const FileInfoSeq& files) { - if(!_dryRun) + for(FileInfoSeq::const_reverse_iterator p = files.rbegin(); p != files.rend(); ++p) { - for(FileInfoSeq::const_reverse_iterator p = files.rbegin(); p != files.rend(); ++p) - { - remove(_dataDir + '/' + p->path); - } - - FileInfoSeq newLocalFiles; - newLocalFiles.reserve(_localFiles.size()); - - set_difference(_localFiles.begin(), - _localFiles.end(), - files.begin(), - files.end(), - back_inserter(newLocalFiles), - FileInfoLess()); - - _localFiles.swap(newLocalFiles); - - FileInfoSeq newRemoveFiles; - - set_difference(_removeFiles.begin(), - _removeFiles.end(), - files.begin(), - files.end(), - back_inserter(newRemoveFiles), - FileInfoLess()); - - _removeFiles.swap(newRemoveFiles); + remove(_dataDir + '/' + p->path); + _log << '-' << *p << endl; } + + FileInfoSeq newLocalFiles; + newLocalFiles.reserve(_localFiles.size()); + + set_difference(_localFiles.begin(), + _localFiles.end(), + files.begin(), + files.end(), + back_inserter(newLocalFiles), + FileInfoLess()); + + _localFiles.swap(newLocalFiles); + + FileInfoSeq newRemoveFiles; + + set_difference(_removeFiles.begin(), + _removeFiles.end(), + files.begin(), + files.end(), + back_inserter(newRemoveFiles), + FileInfoLess()); + + _removeFiles.swap(newRemoveFiles); return true; } @@ -235,96 +423,33 @@ IcePatch2::Patcher::removeFiles(const FileInfoSeq& files) bool IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) { - if(!_dryRun) - { - string pathLog = _dataDir + ".log"; - _updateLog.open(pathLog.c_str()); - if(!_updateLog) - { - throw "cannot open `" + pathLog + "' for writing: " + lastError(); - } - - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _decompress = true; - } - - start(); - } + DecompressorPtr decompressor = new Decompressor(_dataDir); + decompressor->start(); + + bool result; try { - if(!updateFilesInternal(files)) - { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _decompress = false; - notify(); - } - - getThreadControl().join(); - - return false; - } + result = updateFilesInternal(files, decompressor); } catch(...) { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _decompress = false; - notify(); - } - - getThreadControl().join(); - + decompressor->destroy(); + decompressor->getThreadControl().join(); + decompressor->log(_log); throw; } - if(!_dryRun) - { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - if(!_decompressException.empty()) - { - throw _decompressException; - } - _decompress = false; - notify(); - } - - getThreadControl().join(); - - _updateLog.close(); - - FileInfoSeq newLocalFiles; - newLocalFiles.reserve(_localFiles.size()); - - set_union(_localFiles.begin(), - _localFiles.end(), - files.begin(), - files.end(), - back_inserter(newLocalFiles), - FileInfoLess()); - - _localFiles.swap(newLocalFiles); - - FileInfoSeq newUpdateFiles; - - set_difference(_updateFiles.begin(), - _updateFiles.end(), - files.begin(), - files.end(), - back_inserter(newUpdateFiles), - FileInfoLess()); - - _updateFiles.swap(newUpdateFiles); - } + decompressor->destroy(); + decompressor->getThreadControl().join(); + decompressor->log(_log); + decompressor->exception(); - return true; + return result; } bool -IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) +IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const DecompressorPtr& decompressor) { FileInfoSeq::const_iterator p; @@ -343,15 +468,8 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) { if(p->size < 0) // Directory? { - if(!_dryRun) - { - createDirectoryRecursive(_dataDir + '/' + p->path); - - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _updateLog << *p << endl; - } - } + createDirectoryRecursive(_dataDir + '/' + p->path); + _log << '+' << *p << endl; } else // Regular file. { @@ -363,27 +481,24 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) string pathBZ2 = _dataDir + '/' + p->path + ".bz2"; ofstream fileBZ2; - if(!_dryRun) + string dir = getDirname(pathBZ2); + if(!dir.empty()) { - string dir = getDirname(pathBZ2); - if(!dir.empty()) - { - createDirectoryRecursive(dir); - } + createDirectoryRecursive(dir); + } - try - { - removeRecursive(pathBZ2); - } - catch(...) - { - } + try + { + removeRecursive(pathBZ2); + } + catch(...) + { + } - fileBZ2.open(pathBZ2.c_str(), ios::binary); - if(!fileBZ2) - { - throw "cannot open `" + pathBZ2 + "' for writing: " + lastError(); - } + fileBZ2.open(pathBZ2.c_str(), ios::binary); + if(!fileBZ2) + { + throw "cannot open `" + pathBZ2 + "' for writing: " + lastError(); } Int pos = 0; @@ -407,14 +522,11 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) throw "size mismatch for `" + p->path + "'"; } - if(!_dryRun) + fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size()); + + if(!fileBZ2) { - fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size()); - - if(!fileBZ2) - { - throw ": cannot write `" + pathBZ2 + "': " + lastError(); - } + throw ": cannot write `" + pathBZ2 + "': " + lastError(); } pos += bytes.size(); @@ -426,20 +538,10 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) } } - if(!_dryRun) - { - fileBZ2.close(); - - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - if(!_decompressException.empty()) - { - throw _decompressException; - } - _decompressList.push_back(*p); - notify(); - } - } + fileBZ2.close(); + + decompressor->log(_log); + decompressor->add(*p); if(!_feedback->patchEnd()) { @@ -448,51 +550,28 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files) } } - return true; -} + FileInfoSeq newLocalFiles; + newLocalFiles.reserve(_localFiles.size()); + + set_union(_localFiles.begin(), + _localFiles.end(), + files.begin(), + files.end(), + back_inserter(newLocalFiles), + FileInfoLess()); + + _localFiles.swap(newLocalFiles); -void -IcePatch2::Patcher::run() -{ - FileInfo info; - - while(true) - { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - if(!info.path.empty()) - { - _updateLog << info << endl; - } - - while(_decompress && _decompressList.empty()) - { - wait(); - } - - if(!_decompressList.empty()) - { - info = _decompressList.front(); - _decompressList.pop_front(); - } - else - { - return; - } - } + FileInfoSeq newUpdateFiles; + + set_difference(_updateFiles.begin(), + _updateFiles.end(), + files.begin(), + files.end(), + back_inserter(newUpdateFiles), + FileInfoLess()); - try - { - decompressFile(_dataDir + '/' + info.path); - remove(_dataDir + '/' + info.path + ".bz2"); - } - catch(const string& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _decompress = false; - _decompressException = ex; - return; - } - } + _updateFiles.swap(newUpdateFiles); + + return true; } diff --git a/cpp/src/IcePatch2/Util.cpp b/cpp/src/IcePatch2/Util.cpp index ce6c081754b..0358fb83561 100644 --- a/cpp/src/IcePatch2/Util.cpp +++ b/cpp/src/IcePatch2/Util.cpp @@ -861,9 +861,10 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq) infoSeq.push_back(info); } } - } - bool save = false; + sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); + infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); + } { const string pathLog = normalize(pa + ".log"); @@ -871,31 +872,62 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq) ifstream is(pathLog.c_str()); if(is) { - save = true; + FileInfoSeq remove; + FileInfoSeq update; while(is.good()) { + char c; + is >> c; + FileInfo info; is >> info; - + if(is.good()) { - infoSeq.push_back(info); + if(c == '-') + { + remove.push_back(info); + } + else if(c == '+') + { + update.push_back(info); + } } } - } - } - - sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); - infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); - // - // If we merged the sequence with a log file, we save this new - // merged sequence and remove the log file. - // - if(save) - { - saveFileInfoSeq(pa, infoSeq); + sort(remove.begin(), remove.end(), FileInfoLess()); + remove.erase(unique(remove.begin(), remove.end(), FileInfoEqual()), remove.end()); + + sort(update.begin(), update.end(), FileInfoLess()); + update.erase(unique(update.begin(), update.end(), FileInfoEqual()), update.end()); + + FileInfoSeq newInfoSeq; + newInfoSeq.reserve(infoSeq.size()); + + set_difference(infoSeq.begin(), + infoSeq.end(), + remove.begin(), + remove.end(), + back_inserter(newInfoSeq), + FileInfoLess()); + + infoSeq.swap(newInfoSeq); + + newInfoSeq.clear(); + newInfoSeq.reserve(infoSeq.size()); + + set_union(infoSeq.begin(), + infoSeq.end(), + update.begin(), + update.end(), + back_inserter(newInfoSeq), + FileInfoLess()); + + infoSeq.swap(newInfoSeq); + + saveFileInfoSeq(pa, infoSeq); + } } } |