diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-06-29 15:18:21 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-06-29 15:18:21 +0000 |
| commit | c4d79d7160569bef82c4a67b267d78289b91e449 (patch) | |
| tree | 23d390e759271fa4a55b677d09ff0e23b0111a7d /src/FileEntry.cc | |
| parent | e82f870fdc3c1a7fc2c0b66a9f623a5386ece3d6 (diff) | |
2009-06-30 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten PeerStat handling. In the previous implementation,
faster command tries to find slower command. In this new
implementation, slower command tries to find faster command.
PeerStat is now created in each HTTP/FTP request to get download
rate correctly. If the download range is small, the download rate
tends to small and this will occur at the later stage of download.
* src/AbstractCommand.cc
* src/DownloadCommand.cc
* src/FileEntry.cc
* src/FileEntry.h
* src/Request.cc
* src/Request.h
* src/RequestGroup.h
* src/RequestGroupMan.cc
* src/SegmentMan.cc
* src/SegmentMan.h
* test/SegmentManTest.cc
Diffstat (limited to 'src/FileEntry.cc')
| -rw-r--r-- | src/FileEntry.cc | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/src/FileEntry.cc b/src/FileEntry.cc index c07ecbb8..e2e67da5 100644 --- a/src/FileEntry.cc +++ b/src/FileEntry.cc @@ -121,17 +121,71 @@ FileEntry::getRequest(const SharedHandle<URISelector>& selector) } } } else { - req = _requestPool.back(); - _requestPool.pop_back(); + req = _requestPool.front(); + _requestPool.pop_front(); _inFlightRequests.push_back(req); return req; } } +SharedHandle<Request> +FileEntry::findFasterRequest(const SharedHandle<Request>& base) +{ + if(_requestPool.empty()) { + return SharedHandle<Request>(); + } + const SharedHandle<PeerStat>& fastest = _requestPool.front()->getPeerStat(); + if(fastest.isNull()) { + return SharedHandle<Request>(); + } + const SharedHandle<PeerStat>& basestat = base->getPeerStat(); + // TODO1.5 hard coded value. See PREF_STARTUP_IDLE_TIME + const int startupIdleTime = 10; + if(basestat.isNull() || + (basestat->getDownloadStartTime().elapsed(startupIdleTime) && + fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){ + // TODO1.5 we should consider that "fastest" is very slow. + SharedHandle<Request> fastestRequest = _requestPool.front(); + _requestPool.pop_front(); + return fastestRequest; + } + return SharedHandle<Request>(); +} + +class RequestFaster { +public: + bool operator()(const SharedHandle<Request>& lhs, + const SharedHandle<Request>& rhs) const + { + if(lhs->getPeerStat().isNull()) { + return false; + } + if(rhs->getPeerStat().isNull()) { + return true; + } + return + lhs->getPeerStat()->getAvgDownloadSpeed() > rhs->getPeerStat()->getAvgDownloadSpeed(); + } +}; + +void FileEntry::storePool(const SharedHandle<Request>& request) +{ + const SharedHandle<PeerStat>& peerStat = request->getPeerStat(); + if(!peerStat.isNull()) { + // We need to calculate average download speed here in order to + // store Request in the right position in the pool. + peerStat->calculateAvgDownloadSpeed(); + } + std::deque<SharedHandle<Request> >::iterator i = + std::lower_bound(_requestPool.begin(), _requestPool.end(), request, + RequestFaster()); + _requestPool.insert(i, request); +} + void FileEntry::poolRequest(const SharedHandle<Request>& request) { removeRequest(request); - _requestPool.push_back(request); + storePool(request); } bool FileEntry::removeRequest(const SharedHandle<Request>& request) |
