summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES7
-rw-r--r--cpp/doc/Properties.sgml18
-rw-r--r--cpp/include/IcePatch/ClientUtil.h2
-rw-r--r--cpp/include/IcePatch/Util.h4
-rw-r--r--cpp/src/Ice/PropertiesI.cpp3
-rw-r--r--cpp/src/IcePatch/Client.cpp93
-rw-r--r--cpp/src/IcePatch/ClientUtil.cpp7
-rw-r--r--cpp/src/IcePatch/Util.cpp117
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
{