diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/CHANGES | 7 | ||||
-rw-r--r-- | cpp/doc/Properties.sgml | 18 | ||||
-rw-r--r-- | cpp/include/IcePatch/ClientUtil.h | 2 | ||||
-rw-r--r-- | cpp/include/IcePatch/Util.h | 4 | ||||
-rw-r--r-- | cpp/src/Ice/PropertiesI.cpp | 3 | ||||
-rw-r--r-- | cpp/src/IcePatch/Client.cpp | 93 | ||||
-rw-r--r-- | cpp/src/IcePatch/ClientUtil.cpp | 7 | ||||
-rw-r--r-- | cpp/src/IcePatch/Util.cpp | 117 |
8 files changed, 185 insertions, 66 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index 3450b085497..5be4a2d8b6e 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -1,7 +1,12 @@ Changes since version 1.4.0 --------------------------- -- AIX 5.2/VisualAge 6.0 port +- Changed the default behavior of the IcePatch client to dynamically + calculate the unique signatures of local files in order to reduce + the number of cache files, and added the property IcePatch.Dynamic + to control this behavior. + +- AIX 5.2/VisualAge 6.0 port. - Changed the --depend option of slice2java. If you get dependencies for a file x.ice that includes y.ice, the dependency line that is diff --git a/cpp/doc/Properties.sgml b/cpp/doc/Properties.sgml index 139a4860d6b..01a93d7c7bb 100644 --- a/cpp/doc/Properties.sgml +++ b/cpp/doc/Properties.sgml @@ -3181,4 +3181,22 @@ client to skip a directory if its unique signature matches the server's. </section> </section> +<section><title>IcePatch.Dynamic</title> +<section><title>Synopsis</title> +<synopsis> +IcePatch.Dynamic=<replaceable>num</replaceable> +</synopsis> +</section> +<section> +<title>Description</title> +<para> +If <replaceable>num</replaceable> is set to a value larger than zero, +the IcePatch client dynamically calculates the unique signatures of +local files rather than caching the signatures. This reduces the +number of local cache files at the expense of more processing when +comparing directories with the server. The default value is 1. +</para> +</section> +</section> + </section> diff --git a/cpp/include/IcePatch/ClientUtil.h b/cpp/include/IcePatch/ClientUtil.h index 8dcc116b5d4..97706e344b3 100644 --- a/cpp/include/IcePatch/ClientUtil.h +++ b/cpp/include/IcePatch/ClientUtil.h @@ -30,7 +30,7 @@ public: }; ICE_PATCH_API std::string pathToName(const std::string&); -ICE_PATCH_API void getRegular(const IcePatch::RegularPrx&, ProgressCB&); +ICE_PATCH_API Ice::ByteSeq getRegular(const IcePatch::RegularPrx&, ProgressCB&); } diff --git a/cpp/include/IcePatch/Util.h b/cpp/include/IcePatch/Util.h index 8a6d4811144..1bb82853533 100644 --- a/cpp/include/IcePatch/Util.h +++ b/cpp/include/IcePatch/Util.h @@ -47,8 +47,8 @@ ICE_PATCH_API void createDirectory(const std::string&); ICE_PATCH_API Ice::ByteSeq getMD5(const std::string&); ICE_PATCH_API void putMD5(const std::string&, const Ice::ByteSeq&); -ICE_PATCH_API void createMD5(const std::string&, const Ice::LoggerPtr& = 0); -ICE_PATCH_API Ice::ByteSeq calcMD5(const std::string&, const Ice::LoggerPtr& = 0); +ICE_PATCH_API void createMD5(const std::string&, bool, const Ice::LoggerPtr& = 0); +ICE_PATCH_API Ice::ByteSeq calcMD5(const std::string&, bool, const Ice::LoggerPtr& = 0); ICE_PATCH_API Ice::ByteSeq calcPartialMD5(const std::string&, Ice::Int, const Ice::LoggerPtr& = 0); ICE_PATCH_API Ice::ByteSeq getBZ2(const std::string&, Ice::Int, Ice::Int); diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp index 98e9c97d9e8..261af50f2f4 100644 --- a/cpp/src/Ice/PropertiesI.cpp +++ b/cpp/src/Ice/PropertiesI.cpp @@ -195,7 +195,8 @@ static const string icePatchProps[] = "Thorough", "Trace.Files", "UpdatePeriod", - "Directory" + "Directory", + "Dynamic" }; static const string iceSSLProps[] = diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp index 97ace976dc7..d4b3399b935 100644 --- a/cpp/src/IcePatch/Client.cpp +++ b/cpp/src/IcePatch/Client.cpp @@ -40,6 +40,7 @@ private: bool _remove; bool _thorough; + bool _dynamic; }; } @@ -231,6 +232,11 @@ IcePatch::Client::run(int argc, char* argv[]) _thorough = properties->getPropertyAsInt("IcePatch.Thorough") > 0; // + // Check whether we calculate MD5s for files dynamically. + // + _dynamic = properties->getPropertyAsIntWithDefault("IcePatch.Dynamic", 1) > 0; + + // // Create and install the node description factories. // ObjectFactoryPtr factory = new FileDescFactory; @@ -285,7 +291,7 @@ IcePatch::Client::run(int argc, char* argv[]) pos = pos2 + 1; } - cout << pathToName(*p) << endl; + cout << pathToName(*p); string dir = *p; if(dir == ".") @@ -293,7 +299,6 @@ IcePatch::Client::run(int argc, char* argv[]) dir = cwd; } - Long total = 0; ByteSeq md5; try { @@ -302,12 +307,25 @@ IcePatch::Client::run(int argc, char* argv[]) catch(const FileAccessException&) { } - total = topDesc->dir->getTotal(md5); - - Long runningTotal = 0; - patch(topDesc, "", runningTotal, total); - createMD5(dir); + if(!_thorough && md5 == topDesc->md5) + { + // + // Skip the top-level directory if the MD5s match. + // + cout << ": ok" << endl; + } + else + { + // + // Patch the directory. + // + cout << endl; + Long total = topDesc->dir->getTotal(md5); + Long runningTotal = 0; + patch(topDesc, "", runningTotal, total); + createMD5(dir, _dynamic); + } } } catch(const FileAccessException& ex) @@ -477,8 +495,6 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L case FileTypeDirectory: { - cout << " ok" << endl; - if(!_thorough && !subDirDesc->md5.empty()) { ByteSeq md5; @@ -492,10 +508,13 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L if(md5 == subDirDesc->md5) { + cout << " ok" << endl; continue; } } + cout << endl; + break; } @@ -535,6 +554,9 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L bool update = false; FileInfo info = getFileInfo(path, false); + string pathMD5 = path + ".md5"; + FileInfo infoMD5 = getFileInfo(pathMD5, false); + switch(info.type) { case FileTypeNotExist: @@ -554,14 +576,12 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L { ByteSeq md5; - if(_thorough) + if(_thorough || _dynamic) { - md5 = calcMD5(path); + md5 = calcMD5(path, _dynamic); } else { - string pathMD5 = path + ".md5"; - FileInfo infoMD5 = getFileInfo(pathMD5, false); if(infoMD5.type == FileTypeRegular && infoMD5.time >= info.time) { md5 = getMD5(path); @@ -576,12 +596,29 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L else { cout << " ok" << endl; + + // + // Cache the MD5 value if none is present. + // + if(!_dynamic && infoMD5.type == FileTypeNotExist) + { + putMD5(path, md5); + } } break; } } + // + // If we're calculating MD5s dynamically, we need to remove + // any existing MD5 file to be safe. + // + if(_dynamic && infoMD5.type != FileTypeNotExist) + { + removeRecursive(pathMD5); + } + if(update) { orphaned.erase(path + ".bz2"); @@ -592,11 +629,11 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L // // Retrieve file from server. // - getRegular(regDesc->reg, progressCB); + ByteSeq md5 = getRegular(regDesc->reg, progressCB); // // Get the latest file description from server, as - // the file may mave recently changed. + // the file may have recently changed. // regDesc = RegularDescPtr::dynamicCast(regDesc->reg->describe()); if(!regDesc) @@ -609,21 +646,17 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L } // - // Compare the icepatch and locally built MD5s. If - // they differ, try again unless we've hit the + // Compare the MD5s of the server and the local file. + // If they differ, try again unless we've hit the // retry limit. // - ByteSeq md5; - string pathMD5 = path + ".md5"; - FileInfo infoMD5 = getFileInfo(pathMD5, false); - if(infoMD5.type == FileTypeRegular) - { - md5 = getMD5(path); - } - if(regDesc->md5 == md5) { runningTotal += regDesc->reg->getBZ2Size(); + if(!_dynamic) + { + putMD5(path, md5); + } break; } else if(retries < 3) @@ -635,15 +668,7 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent, L removeRecursive(path); FileAccessException ex; - ex.reason = "Retry count exceeded while patching `" + path + "':\n"; - if(infoMD5.type == FileTypeRegular) - { - ex.reason += "MD5 mismatch"; - } - else - { - ex.reason += "MD5 file not found"; - } + ex.reason = "Retry count exceeded while patching `" + path + "':\nMD5 mismatch"; throw ex; } } diff --git a/cpp/src/IcePatch/ClientUtil.cpp b/cpp/src/IcePatch/ClientUtil.cpp index 07610ea2938..3d08927196c 100644 --- a/cpp/src/IcePatch/ClientUtil.cpp +++ b/cpp/src/IcePatch/ClientUtil.cpp @@ -30,7 +30,7 @@ IcePatch::pathToName(const string& path) } } -void +ByteSeq IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB) { string path = identityToPath(regular->ice_getIdentity()); @@ -210,8 +210,5 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB) throw ex; } - // - // Create a MD5 file for the original file. - // - createMD5(path); + return calcMD5(path, false); } diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp index 6bb0f3b4e67..f586343de78 100644 --- a/cpp/src/IcePatch/Util.cpp +++ b/cpp/src/IcePatch/Util.cpp @@ -520,7 +520,7 @@ IcePatch::putMD5(const string& path, const ByteSeq& bytesMD5) } void -IcePatch::createMD5(const string& path, const LoggerPtr& logger) +IcePatch::createMD5(const string& path, bool dynamic, const LoggerPtr& logger) { // // The current directory is not permissible for MD5 value @@ -531,7 +531,7 @@ IcePatch::createMD5(const string& path, const LoggerPtr& logger) // // Calculate and save the MD5 hash value. // - ByteSeq bytesMD5 = calcMD5(path, logger); + ByteSeq bytesMD5 = calcMD5(path, dynamic, logger); putMD5(path, bytesMD5); @@ -543,34 +543,107 @@ IcePatch::createMD5(const string& path, const LoggerPtr& logger) } ByteSeq -IcePatch::calcMD5(const string& path, const LoggerPtr& logger) +IcePatch::calcMD5(const string& path, bool dynamic, const LoggerPtr& logger) { ByteSeq bytes; FileInfo info = getFileInfo(path, true, logger); if(info.type == FileTypeDirectory) { - // - // Create a summary of all MD5 files. - // StringSeq paths = readDirectory(path); - for(StringSeq::const_iterator p = paths.begin(); p < paths.end(); ++p) - { - if(getSuffix(*p) == "md5") - { - string plainPath = removeSuffix(*p); - - // - // We must take the filename into account, so that - // renaming a file will change the summary MD5. - // + if(dynamic) + { + // + // Dynamically compute the MD5s for all files, but reuse the MD5s + // already computed for subdirectories. + // + for(StringSeq::const_iterator p = paths.begin(); p < paths.end(); ++p) + { + if(!ignoreSuffix(*p)) + { + ByteSeq subBytesMD5; + FileInfo subInfo = getFileInfo(*p, true, logger); + if(subInfo.type == FileTypeDirectory) + { + subBytesMD5 = getMD5(*p); + } + else if(subInfo.type == FileTypeRegular) + { + subBytesMD5 = calcMD5(*p, dynamic, logger); + } + + // + // We must take the filename into account, so that + // renaming a file will change the summary MD5. + // + string plainFile = p->substr(p->rfind('/') + 1); + copy(plainFile.begin(), plainFile.end(), back_inserter(bytes)); + copy(subBytesMD5.begin(), subBytesMD5.end(), back_inserter(bytes)); + } + +#if 0 + string plainPath; + ByteSeq subBytesMD5; + if(getSuffix(*p) == "md5") + { + plainPath = removeSuffix(*p); + FileInfo plainPathInfo = getFileInfo(plainPath, true, logger); + if(plainPathInfo.type != FileTypeDirectory) + { + continue; // Ignore MD5 for a regular file. + } + + subBytesMD5 = getMD5(plainPath); + } + else if(!ignoreSuffix(*p)) + { + plainPath = *p; + FileInfo plainPathInfo = getFileInfo(*p, true, logger); + if(plainPathInfo.type != FileTypeRegular) + { + continue; + } + + subBytesMD5 = calcMD5(plainPath, dynamic, logger); + } + else + { + continue; + } + + // + // We must take the filename into account, so that + // renaming a file will change the summary MD5. + // string plainFile = plainPath.substr(plainPath.rfind('/') + 1); - copy(plainFile.begin(), plainFile.end(), back_inserter(bytes)); - - ByteSeq subBytesMD5 = getMD5(plainPath); - copy(subBytesMD5.begin(), subBytesMD5.end(), back_inserter(bytes)); - } - } + copy(plainFile.begin(), plainFile.end(), back_inserter(bytes)); + copy(subBytesMD5.begin(), subBytesMD5.end(), back_inserter(bytes)); +#endif + } + } + else + { + // + // Create a summary of all MD5 files. + // + for(StringSeq::const_iterator p = paths.begin(); p < paths.end(); ++p) + { + if(getSuffix(*p) == "md5") + { + string plainPath = removeSuffix(*p); + + // + // We must take the filename into account, so that + // renaming a file will change the summary MD5. + // + string plainFile = plainPath.substr(plainPath.rfind('/') + 1); + copy(plainFile.begin(), plainFile.end(), back_inserter(bytes)); + + ByteSeq subBytesMD5 = getMD5(plainPath); + copy(subBytesMD5.begin(), subBytesMD5.end(), back_inserter(bytes)); + } + } + } } else { |