summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2002-04-28 13:53:42 +0000
committerMarc Laukien <marc@zeroc.com>2002-04-28 13:53:42 +0000
commitee69188a792f0d2b85838256496b51d685689fa1 (patch)
tree54c36305a192fadea82ee551b7b19ff35d97738f /cpp
parentpython test scripts cleanup (diff)
downloadice-ee69188a792f0d2b85838256496b51d685689fa1.tar.bz2
ice-ee69188a792f0d2b85838256496b51d685689fa1.tar.xz
ice-ee69188a792f0d2b85838256496b51d685689fa1.zip
partial retransmission for IcePatch
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/IcePatch/Util.h5
-rw-r--r--cpp/slice/IcePatch/IcePatch.ice3
-rw-r--r--cpp/src/IcePatch/Client.cpp19
-rw-r--r--cpp/src/IcePatch/IcePatchI.cpp34
-rw-r--r--cpp/src/IcePatch/IcePatchI.h1
-rw-r--r--cpp/src/IcePatch/Util.cpp115
6 files changed, 152 insertions, 25 deletions
diff --git a/cpp/include/IcePatch/Util.h b/cpp/include/IcePatch/Util.h
index 945b95fc728..5b02b854761 100644
--- a/cpp/include/IcePatch/Util.h
+++ b/cpp/include/IcePatch/Util.h
@@ -47,6 +47,7 @@ ICE_PATCH_API Ice::StringSeq readDirectory(const std::string&);
ICE_PATCH_API void createDirectory(const std::string&);
ICE_PATCH_API Ice::ByteSeq getMD5(const std::string&);
+ICE_PATCH_API Ice::ByteSeq getPartialMD5(const std::string&, Ice::Int);
ICE_PATCH_API void createMD5(const std::string&);
ICE_PATCH_API Ice::ByteSeq getBZ2(const std::string&, Ice::Int, Ice::Int);
@@ -56,11 +57,11 @@ class ICE_PATCH_API ProgressCB
{
public:
- virtual void startDownload(Ice::Int) = 0;
+ virtual void startDownload(Ice::Int, Ice::Int) = 0;
virtual void updateDownload(Ice::Int, Ice::Int) = 0;
virtual void finishedDownload(Ice::Int) = 0;
- virtual void startUncompress(Ice::Int) = 0;
+ virtual void startUncompress(Ice::Int, Ice::Int) = 0;
virtual void updateUncompress(Ice::Int, Ice::Int) = 0;
virtual void finishedUncompress(Ice::Int) = 0;
};
diff --git a/cpp/slice/IcePatch/IcePatch.ice b/cpp/slice/IcePatch/IcePatch.ice
index e386579fc38..dd9f392146e 100644
--- a/cpp/slice/IcePatch/IcePatch.ice
+++ b/cpp/slice/IcePatch/IcePatch.ice
@@ -55,6 +55,9 @@ interface Regular extends File
Ice::ByteSeq getBZ2(int pos, int num)
throws FileAccessException, BusyException;
+
+ Ice::ByteSeq getBZ2MD5(int size)
+ throws FileAccessException, BusyException;
};
class RegularDesc extends FileDesc
diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp
index d238528e654..0afbea8c998 100644
--- a/cpp/src/IcePatch/Client.cpp
+++ b/cpp/src/IcePatch/Client.cpp
@@ -241,9 +241,10 @@ class MyProgressCB : public ProgressCB
{
public:
- virtual void startDownload(Int)
+ virtual void startDownload(Int total, Int pos)
{
- cout << " download 0%" << flush;
+ Ice::Int percent = pos * 100 / total;
+ cout << " download " << setw(3) << percent << "%" << flush;
}
virtual void updateDownload(Int total, Int pos)
@@ -252,19 +253,21 @@ public:
cout << "\b\b\b\b" << setw(3) << percent << "%" << flush;
}
- virtual void finishedDownload(Int)
+ virtual void finishedDownload(Int total)
{
- cout << "\b\b\b\b" << setw(3) << 100 << "%" << flush;
+ updateDownload(total, total);
}
- virtual void startUncompress(Int)
+ virtual void startUncompress(Int total, Int pos)
{
- cout << " uncompress 0%" << flush;
+ Ice::Int percent = pos * 100 / total;
+ cout << " uncompress " << setw(3) << percent << "%" << flush;
}
-
+
virtual void updateUncompress(Int total, Int pos)
{
- updateDownload(total, pos);
+ Ice::Int percent = pos * 100 / total;
+ cout << "\b\b\b\b" << setw(3) << percent << "%" << flush;
}
virtual void finishedUncompress(Int total)
diff --git a/cpp/src/IcePatch/IcePatchI.cpp b/cpp/src/IcePatch/IcePatchI.cpp
index 04757c3d061..881ede32971 100644
--- a/cpp/src/IcePatch/IcePatchI.cpp
+++ b/cpp/src/IcePatch/IcePatchI.cpp
@@ -225,3 +225,37 @@ IcePatch::RegularI::getBZ2(Ice::Int pos, Ice::Int num, const Ice::Current& curre
throw BusyException();
}
}
+
+ByteSeq
+IcePatch::RegularI::getBZ2MD5(Ice::Int size, const Ice::Current& current)
+{
+ try
+ {
+ IceUtil::RWRecMutex::TryRLock sync(_globalMutex, _busyTimeout);
+ string path = identityToPath(current.identity);
+
+ FileInfo info = getFileInfo(path, true);
+ FileInfo infoBZ2 = getFileInfo(path + ".bz2", false);
+ if (infoBZ2.type != FileTypeRegular || infoBZ2.time < info.time)
+ {
+ sync.timedUpgrade(_busyTimeout);
+ infoBZ2 = getFileInfo(path + ".bz2", false);
+ if (infoBZ2.type != FileTypeRegular || infoBZ2.time < info.time)
+ {
+ createBZ2(path);
+
+ if (_traceLevel > 0)
+ {
+ Trace out(_logger, "IcePatch");
+ out << "created .bz2 file for `" << path << "'";
+ }
+ }
+ }
+
+ return IcePatch::getPartialMD5(path + ".bz2", size);
+ }
+ catch (const IceUtil::LockedException&)
+ {
+ throw BusyException();
+ }
+}
diff --git a/cpp/src/IcePatch/IcePatchI.h b/cpp/src/IcePatch/IcePatchI.h
index 7092e5ce0ed..040b7d9e9c8 100644
--- a/cpp/src/IcePatch/IcePatchI.h
+++ b/cpp/src/IcePatch/IcePatchI.h
@@ -54,6 +54,7 @@ public:
virtual FileDescPtr describe(const Ice::Current&);
virtual Ice::Int getBZ2Size(const Ice::Current&);
virtual Ice::ByteSeq getBZ2(Ice::Int, Ice::Int, const Ice::Current&);
+ virtual Ice::ByteSeq getBZ2MD5(Ice::Int, const Ice::Current&);
};
}
diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp
index e22a9886043..04c830bc41a 100644
--- a/cpp/src/IcePatch/Util.cpp
+++ b/cpp/src/IcePatch/Util.cpp
@@ -298,6 +298,55 @@ IcePatch::getMD5(const string& path)
return bytesMD5;
}
+ByteSeq
+IcePatch::getPartialMD5(const string& path, Int size)
+{
+ if (size < 0)
+ {
+ FileAccessException ex;
+ ex.reason = "negative file size is illegal";
+ throw ex;
+ }
+
+ //
+ // Read the original file partially.
+ //
+ FileInfo info = getFileInfo(path, true);
+ size = std::min(size, static_cast<Int>(info.size));
+ ifstream file(path.c_str(), ios::binary);
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+ ByteSeq bytes;
+ bytes.resize(size);
+ file.read(&bytes[0], bytes.size());
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+ if (file.gcount() < static_cast<int>(bytes.size()))
+ {
+ FileAccessException ex;
+ ex.reason = "could not read all bytes from `" + path + "'";
+ throw ex;
+ }
+ file.close();
+
+ //
+ // Create the MD5 hash value.
+ //
+ ByteSeq bytesMD5;
+ bytesMD5.resize(16);
+ MD5(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(), reinterpret_cast<unsigned char*>(&bytesMD5[0]));
+
+ return bytesMD5;
+}
+
void
IcePatch::createMD5(const string& path)
{
@@ -374,6 +423,27 @@ IcePatch::createMD5(const string& path)
ByteSeq
IcePatch::getBZ2(const string& path, Int pos, Int num)
{
+ if (pos < 0)
+ {
+ FileAccessException ex;
+ ex.reason = "negative read offset is illegal";
+ throw ex;
+ }
+
+ if (num < 0)
+ {
+ FileAccessException ex;
+ ex.reason = "negative data segment size is illegal";
+ throw ex;
+ }
+
+ if (num > 1024 * 1024)
+ {
+ FileAccessException ex;
+ ex.reason = "maxium data segment size exceeded";
+ throw ex;
+ }
+
string pathBZ2 = path + ".bz2";
ifstream fileBZ2(pathBZ2.c_str(), ios::binary);
if (!fileBZ2)
@@ -513,13 +583,29 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
string path = identityToPath(regular->ice_getIdentity());
string pathBZ2 = path + ".bz2";
Int totalBZ2 = regular->getBZ2Size();
+ Int posBZ2 = 0;
+
+ //
+ // Check for partial BZ2 file.
+ //
+ FileInfo infoBZ2 = getFileInfo(pathBZ2, false);
+ if (infoBZ2.type == FileTypeRegular)
+ {
+ ByteSeq remoteBZ2MD5 = regular->getBZ2MD5(infoBZ2.size);
+ ByteSeq localBZ2MD5 = getPartialMD5(pathBZ2, infoBZ2.size);
+
+ if (remoteBZ2MD5 == localBZ2MD5)
+ {
+ posBZ2 = infoBZ2.size;
+ }
+ }
//
// Get the BZ2 file.
//
- progressCB.startDownload(totalBZ2);
+ progressCB.startDownload(totalBZ2, posBZ2);
- ofstream fileBZ2(pathBZ2.c_str(), ios::binary);
+ ofstream fileBZ2(pathBZ2.c_str(), ios::binary | (posBZ2 ? ios::app : 0));
if (!fileBZ2)
{
FileAccessException ex;
@@ -527,19 +613,18 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
throw ex;
}
- ByteSeq bytesBZ2;
- Int pos = 0;
- while(pos < totalBZ2)
+ while(posBZ2 < totalBZ2)
{
- static const Int num = 64 * 1024;
+ static const Int numBZ2 = 64 * 1024;
- bytesBZ2 = regular->getBZ2(pos, num);
+ ByteSeq bytesBZ2 = regular->getBZ2(posBZ2, numBZ2);
if (bytesBZ2.empty())
{
break;
}
+ sleep(1);
- pos += bytesBZ2.size();
+ posBZ2 += bytesBZ2.size();
fileBZ2.write(&bytesBZ2[0], bytesBZ2.size());
if (!fileBZ2)
@@ -549,12 +634,12 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
throw ex;
}
- if (static_cast<Int>(bytesBZ2.size()) < num)
+ if (static_cast<Int>(bytesBZ2.size()) < numBZ2)
{
break;
}
- progressCB.updateDownload(totalBZ2, pos);
+ progressCB.updateDownload(totalBZ2, posBZ2);
}
progressCB.finishedDownload(totalBZ2);
@@ -594,14 +679,14 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
throw ex;
}
- static const Int num = 64 * 1024;
- Byte bytes[num];
+ static const Int numBZ2 = 64 * 1024;
+ Byte bytesBZ2[numBZ2];
- progressCB.startUncompress(totalBZ2);
+ progressCB.startUncompress(totalBZ2, 0);
while (bzError != BZ_STREAM_END)
{
- int sz = BZ2_bzRead(&bzError, bzFile, bytes, num);
+ int sz = BZ2_bzRead(&bzError, bzFile, bytesBZ2, numBZ2);
if (bzError != BZ_OK && bzError != BZ_STREAM_END)
{
FileAccessException ex;
@@ -629,7 +714,7 @@ IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
progressCB.updateUncompress(totalBZ2, pos);
- file.write(bytes, sz);
+ file.write(bytesBZ2, sz);
if (!file)
{
FileAccessException ex;