summaryrefslogtreecommitdiff
path: root/src/FileEntry.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-06-29 15:18:21 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-06-29 15:18:21 +0000
commitc4d79d7160569bef82c4a67b267d78289b91e449 (patch)
tree23d390e759271fa4a55b677d09ff0e23b0111a7d /src/FileEntry.cc
parente82f870fdc3c1a7fc2c0b66a9f623a5386ece3d6 (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.cc60
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)