Copy-from-install support in TerraSync

Allows repositories to be initialised based on data in the install.
This avoids duplicate downloading of the Model and Airport data,
and the starting scenery.

Requires a corresponding FlightGear change to be functional.
This commit is contained in:
James Turner
2016-08-18 16:21:31 +01:00
parent 6b82b78c7c
commit d7d59b08a2
3 changed files with 74 additions and 0 deletions

View File

@@ -150,6 +150,7 @@ public:
typedef std::vector<HTTPDirectory*> DirectoryVector;
DirectoryVector directories;
SGPath installedCopyPath;
};
class HTTPDirectory
@@ -255,6 +256,54 @@ public:
}
}
void copyInstalledChildren()
{
if (_repository->installedCopyPath.isNull()) {
return;
}
string_list indexNames = indexChildren();
const_string_list_iterator nameIt = indexNames.begin();
for (; nameIt != indexNames.end(); ++nameIt) {
SGPath p(absolutePath());
p.append(*nameIt);
if (p.exists()) {
continue; // only copy if the file is missing entirely
}
ChildInfoList::iterator c = findIndexChild(*nameIt);
if (c->type == ChildInfo::DirectoryType) {
continue; // only care about files
}
SGPath cp = _repository->installedCopyPath;
cp.append(relativePath());
cp.append(*nameIt);
if (!cp.exists()) {
continue;
}
SG_LOG(SG_TERRASYNC, SG_BULK, "new child, copying existing file" << cp << p);
SGBinaryFile src(cp);
SGBinaryFile dst(p);
src.open(SG_IO_IN);
dst.open(SG_IO_OUT);
char* buf = (char*) malloc(cp.sizeInBytes());
if (!buf) {
continue;
}
src.read(buf, cp.sizeInBytes());
dst.write(buf, cp.sizeInBytes());
src.close();
dst.close();
free(buf);
}
}
void updateChildrenBasedOnHash()
{
// if we got here for a dir which is still updating or excluded
@@ -263,6 +312,8 @@ public:
return;
}
copyInstalledChildren();
string_list indexNames = indexChildren(),
toBeUpdated, orphans;
simgear::Dir d(absolutePath());
@@ -723,6 +774,11 @@ size_t HTTPRepository::bytesDownloaded() const
return result;
}
void HTTPRepository::setInstalledCopyPath(const SGPath& copyPath)
{
_d->installedCopyPath = copyPath;
}
HTTPRepository::ResultCode
HTTPRepository::failure() const
{

View File

@@ -71,6 +71,12 @@ public:
virtual size_t bytesToDownload() const;
virtual size_t bytesDownloaded() const;
/**
* optionally provide the location of an installer copy of this
* repository. When a file is missing it will be copied from this tree.
*/
void setInstalledCopyPath(const SGPath& copyPath);
private:
bool isBare() const;

View File

@@ -274,6 +274,8 @@ public:
void setLocalDir(string dir) { _local_dir = stripPath(dir);}
string getLocalDir() { return _local_dir;}
void setInstalledDir(const SGPath& p) { _installRoot = p; }
void setAllowedErrorCount(int errors)
{
SGGuard<SGMutex> g(_stateLock);
@@ -331,6 +333,7 @@ private:
string _local_dir;
SGPath _persistentCachePath;
string _httpServer;
SGPath _installRoot;
TerrasyncThreadState _state;
SGMutex _stateLock;
@@ -547,6 +550,12 @@ void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
slot.repository->setEntireRepositoryMode();
slot.repository->setBaseUrl(_httpServer + "/" + slot.currentItem._dir);
if (_installRoot.exists()) {
SGPath p = _installRoot;
p.append(slot.currentItem._dir);
slot.repository->setInstalledCopyPath(p);
}
try {
slot.repository->update();
} catch (sg_exception& e) {
@@ -825,6 +834,9 @@ void SGTerraSync::reinit()
std::string httpServer(_terraRoot->getStringValue("http-server",""));
_workerThread->setHTTPServer(httpServer);
_workerThread->setLocalDir(_terraRoot->getStringValue("scenery-dir",""));
SGPath installPath(_terraRoot->getStringValue("installation-dir"));
_workerThread->setInstalledDir(installPath);
_workerThread->setAllowedErrorCount(_terraRoot->getIntValue("max-errors",5));
_workerThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0));