From c199c952186357d53657e85c0b02cfd3f0100d7e Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 22 Mar 2016 21:14:17 +0000 Subject: [PATCH] Expose total bytes to download / remaining For HTTP repositories, support some additional metrics about ongoing transfers. Not currently exposed via properties / TerraSync API, but will be shortly. --- simgear/io/AbstractRepository.cxx | 5 +++ simgear/io/AbstractRepository.hxx | 2 + simgear/io/HTTPRepository.cxx | 66 +++++++++++++++++++++++++------ simgear/io/HTTPRepository.hxx | 4 ++ 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/simgear/io/AbstractRepository.cxx b/simgear/io/AbstractRepository.cxx index 0a935f34..e9e53efc 100644 --- a/simgear/io/AbstractRepository.cxx +++ b/simgear/io/AbstractRepository.cxx @@ -26,4 +26,9 @@ AbstractRepository::~AbstractRepository() } +size_t AbstractRepository::bytesStillToDownload() const +{ + return 0; +} + } // of namespace simgear diff --git a/simgear/io/AbstractRepository.hxx b/simgear/io/AbstractRepository.hxx index d8fe26cf..8d586930 100644 --- a/simgear/io/AbstractRepository.hxx +++ b/simgear/io/AbstractRepository.hxx @@ -47,6 +47,8 @@ public: virtual bool isDoingSync() const = 0; + virtual size_t bytesStillToDownload() const; + enum ResultCode { REPO_NO_ERROR = 0, REPO_ERROR_NOT_FOUND, diff --git a/simgear/io/HTTPRepository.cxx b/simgear/io/HTTPRepository.cxx index be2385d6..e1df923b 100644 --- a/simgear/io/HTTPRepository.cxx +++ b/simgear/io/HTTPRepository.cxx @@ -109,8 +109,19 @@ namespace simgear _directory = 0; abort("Repository cancelled request"); } + + size_t contentSize() const + { + return _contentSize; + } + + void setContentSize(size_t sz) + { + _contentSize = sz; + } protected: HTTPDirectory* _directory; + size_t _contentSize; }; typedef SGSharedPtr RepoRequestPtr; @@ -142,7 +153,8 @@ public: HTTPRepoPrivate(HTTPRepository* parent) : p(parent), isUpdating(false), - status(AbstractRepository::REPO_NO_ERROR) + status(AbstractRepository::REPO_NO_ERROR), + totalDownloaded(0) { ; } ~HTTPRepoPrivate(); @@ -154,9 +166,12 @@ public: bool isUpdating; AbstractRepository::ResultCode status; HTTPDirectory* rootDir; + size_t totalDownloaded; - HTTP::Request_ptr updateFile(HTTPDirectory* dir, const std::string& name); - HTTP::Request_ptr updateDir(HTTPDirectory* dir, const std::string& hash); + HTTP::Request_ptr updateFile(HTTPDirectory* dir, const std::string& name, + size_t sz); + HTTP::Request_ptr updateDir(HTTPDirectory* dir, const std::string& hash, + size_t sz); std::string hashForPath(const SGPath& p); void updatedFileContents(const SGPath& p, const std::string& newHash); @@ -235,7 +250,7 @@ public: if (p.exists()) { try { // already exists on disk - bool ok = parseDirIndex(children); + parseDirIndex(children); std::sort(children.begin(), children.end()); } catch (sg_exception& e) { // parsing cache failed @@ -361,12 +376,12 @@ public: } if (cit->type == ChildInfo::FileType) { - _repository->updateFile(this, *it); + _repository->updateFile(this, *it, cit->sizeInBytes); } else { SGPath p(relativePath()); p.append(*it); HTTPDirectory* childDir = _repository->getOrCreateDirectory(p.str()); - _repository->updateDir(childDir, cit->hash); + _repository->updateDir(childDir, cit->hash, cit->sizeInBytes); } } } @@ -383,7 +398,7 @@ public: return _relativePath; } - void didUpdateFile(const std::string& file, const std::string& hash) + void didUpdateFile(const std::string& file, const std::string& hash, size_t sz) { // check hash matches what we expected ChildInfoList::iterator it = findIndexChild(file); @@ -397,6 +412,7 @@ public: _repository->failedToUpdateChild(_relativePath, AbstractRepository::REPO_ERROR_CHECKSUM); } else { _repository->updatedFileContents(fpath, hash); + _repository->totalDownloaded += sz; //SG_LOG(SG_TERRASYNC, SG_INFO, "did update:" << fpath); } // of hash matches } // of found in child list @@ -561,7 +577,7 @@ void HTTPRepository::update() _d->status = REPO_NO_ERROR; _d->isUpdating = true; _d->failures.clear(); - _d->updateDir(_d->rootDir, std::string()); + _d->updateDir(_d->rootDir, std::string(), 0); } bool HTTPRepository::isDoingSync() const @@ -573,6 +589,30 @@ bool HTTPRepository::isDoingSync() const return _d->isUpdating; } +size_t HTTPRepository::bytesToDownload() const +{ + size_t result = 0; + + HTTPRepoPrivate::RequestVector::const_iterator r; + for (r = _d->requests.begin(); r != _d->requests.end(); ++r) { + result += (*r)->contentSize() - (*r)->responseBytesReceived(); + } + + return result; +} + +size_t HTTPRepository::bytesDownloaded() const +{ + size_t result = _d->totalDownloaded; + + HTTPRepoPrivate::RequestVector::const_iterator r; + for (r = _d->requests.begin(); r != _d->requests.end(); ++r) { + result += (*r)->responseBytesReceived(); + } + + return result; +} + AbstractRepository::ResultCode HTTPRepository::failure() const { @@ -617,7 +657,7 @@ HTTPRepository::failure() const file->close(); if (responseCode() == 200) { std::string hash = strutils::encodeHex(sha1_result(&hashContext), HASH_LENGTH); - _directory->didUpdateFile(fileName, hash); + _directory->didUpdateFile(fileName, hash, contentSize()); //SG_LOG(SG_TERRASYNC, SG_INFO, "got file " << fileName << " in " << _directory->absolutePath()); } else if (responseCode() == 404) { _directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_FILE_NOT_FOUND); @@ -714,6 +754,8 @@ HTTPRepository::failure() const //SG_LOG(SG_TERRASYNC, SG_INFO, "updated dir index " << _directory->absolutePath()); } + _directory->repository()->totalDownloaded += contentSize(); + try { // either way we've confirmed the index is valid so update // children now @@ -769,17 +811,19 @@ HTTPRepository::failure() const } } - HTTP::Request_ptr HTTPRepoPrivate::updateFile(HTTPDirectory* dir, const std::string& name) + HTTP::Request_ptr HTTPRepoPrivate::updateFile(HTTPDirectory* dir, const std::string& name, size_t sz) { RepoRequestPtr r(new FileGetRequest(dir, name)); + r->setContentSize(sz); requests.push_back(r); http->makeRequest(r); return r; } - HTTP::Request_ptr HTTPRepoPrivate::updateDir(HTTPDirectory* dir, const std::string& hash) + HTTP::Request_ptr HTTPRepoPrivate::updateDir(HTTPDirectory* dir, const std::string& hash, size_t sz) { RepoRequestPtr r(new DirGetRequest(dir, hash)); + r->setContentSize(sz); requests.push_back(r); http->makeRequest(r); return r; diff --git a/simgear/io/HTTPRepository.hxx b/simgear/io/HTTPRepository.hxx index 7b8181ee..4a355441 100644 --- a/simgear/io/HTTPRepository.hxx +++ b/simgear/io/HTTPRepository.hxx @@ -46,6 +46,10 @@ public: virtual bool isDoingSync() const; virtual ResultCode failure() const; + + virtual size_t bytesToDownload() const; + + virtual size_t bytesDownloaded() const; private: bool isBare() const; -- 2.39.5