Index: src/AbstractCommand.cc =================================================================== --- src/AbstractCommand.cc (revision 51) +++ src/AbstractCommand.cc (revision 52) @@ -188,7 +188,7 @@ void AbstractCommand::tryReserved() { _requestGroup->removeServerHost(cuid); Commands commands; - _requestGroup->createNextCommand(commands, e, 1); + _requestGroup->createNextCommand(commands, e, 1, true); e->setNoWait(true); e->addCommand(commands); } Index: src/RequestGroupMan.cc =================================================================== --- src/RequestGroupMan.cc (revision 51) +++ src/RequestGroupMan.cc (revision 52) @@ -49,6 +49,7 @@ #include "SegmentMan.h" #include "ServerStatURISelector.h" #include "InOrderURISelector.h" +#include "AdaptiveURISelector.h" #include "Option.h" #include "prefs.h" #include "File.h" @@ -194,9 +195,18 @@ if(group->getNumCommand() == 0) { // Collect statistics during download in PeerStats and update/register // ServerStatMan + unsigned int multiConnectionTotalSpeed = 0; + float multiConnectionAverageSpeed = 0; if(!group->getSegmentMan().isNull()) { const std::deque<SharedHandle<PeerStat> >& peerStats = group->getSegmentMan()->getPeerStats(); + if(peerStats.size() > 1) { + for(std::deque<SharedHandle<PeerStat> >::const_iterator i = peerStats.begin(); + i != peerStats.end(); ++i) { + multiConnectionTotalSpeed += (*i)->getAvgDownloadSpeed(); + } + multiConnectionAverageSpeed = (float)multiConnectionTotalSpeed/(float)peerStats.size(); + } for(std::deque<SharedHandle<PeerStat> >::const_iterator i = peerStats.begin(); i != peerStats.end(); ++i) { if((*i)->getHostname().empty() || (*i)->getProtocol().empty()) { @@ -205,7 +215,14 @@ SharedHandle<ServerStat> ss = _requestGroupMan->getOrCreateServerStat((*i)->getHostname(), (*i)->getProtocol()); + ss->increaseCounter(); ss->updateDownloadSpeed((*i)->getAvgDownloadSpeed()); + if(peerStats.size() == 1) { + ss->updateSingleConnectionAvgSpeed((*i)->getAvgDownloadSpeed()); + } + else { + ss->updateMultiConnectionAvgSpeed((int)multiConnectionAverageSpeed); + } } } } @@ -255,6 +272,9 @@ } else if(uriSelectorValue == V_INORDER) { requestGroup->setURISelector (SharedHandle<URISelector>(new InOrderURISelector())); + } else if(uriSelectorValue == V_ADAPTIVE) { + requestGroup->setURISelector + (SharedHandle<URISelector>(new AdaptiveURISelector(_serverStatMan, requestGroup))); } } Index: src/OptionHandlerFactory.cc =================================================================== --- src/OptionHandlerFactory.cc (revision 51) +++ src/OptionHandlerFactory.cc (revision 52) @@ -144,7 +144,7 @@ } handlers.push_back(SH(new BooleanOptionHandler(PREF_BT_SEED_UNVERIFIED))); { - const std::string params[] = { V_INORDER, V_FEEDBACK }; + const std::string params[] = { V_INORDER, V_FEEDBACK, V_ADAPTIVE }; handlers.push_back(SH(new ParameterOptionHandler (PREF_URI_SELECTOR, std::deque<std::string> Index: src/InOrderURISelector.cc =================================================================== --- src/InOrderURISelector.cc (revision 51) +++ src/InOrderURISelector.cc (revision 52) @@ -41,7 +41,7 @@ InOrderURISelector::~InOrderURISelector() {} -std::string InOrderURISelector::select(std::deque<std::string>& uris) +std::string InOrderURISelector::select(std::deque<std::string>& uris, bool reserved) { if(uris.empty()) { return A2STR::NIL; Index: src/URISelector.h =================================================================== --- src/URISelector.h (revision 51) +++ src/URISelector.h (revision 52) @@ -44,7 +44,9 @@ public: virtual ~URISelector() {} - virtual std::string select(std::deque<std::string>& uris) = 0; + virtual std::string select(std::deque<std::string>& uris, bool reserved) = 0; + + virtual void resetCounters() { return; }; }; } // namespace aria2 Index: src/RequestGroup.cc =================================================================== --- src/RequestGroup.cc (revision 51) +++ src/RequestGroup.cc (revision 52) @@ -293,7 +293,7 @@ // TODO I assume here when totallength is set to DownloadContext and it is // not 0, then filepath is also set DownloadContext correctly.... if(_downloadContext->getTotalLength() == 0) { - createNextCommand(commands, e, 1); + createNextCommand(commands, e, 1, false); }else { if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) { throw DownloadFailureException @@ -498,18 +498,21 @@ numCommand += numAdj; } if(numCommand > 0) { - createNextCommand(commands, e, numCommand); + createNextCommand(commands, e, numCommand, false); } } void RequestGroup::createNextCommand(std::deque<Command*>& commands, DownloadEngine* e, unsigned int numCommand, + bool reserved, const std::string& method) { std::deque<std::string> pendingURIs; for(; !_uris.empty() && numCommand--; ) { - std::string uri = _uriSelector->select(_uris); + std::string uri = _uriSelector->select(_uris, reserved); + if(uri.size() == 0) + continue; RequestHandle req(new Request()); if(req->setUrl(uri)) { ServerHostHandle sv; @@ -971,6 +974,7 @@ { _logger->notice(MSG_FILE_DOWNLOAD_COMPLETED, getFilePath().c_str()); + _uriSelector->resetCounters(); #ifdef ENABLE_BITTORRENT TransferStat stat = calculateStat(); SharedHandle<BtContext> ctx = dynamic_pointer_cast<BtContext>(_downloadContext); Index: src/ServerStatMan.cc =================================================================== --- src/ServerStatMan.cc (revision 51) +++ src/ServerStatMan.cc (revision 52) @@ -86,7 +86,10 @@ static const std::string S_HOST = "host"; static const std::string S_PROTOCOL = "protocol"; static const std::string S_DL_SPEED = "dl_speed"; + static const std::string S_SC_AVG_SPEED = "sc_avg_speed"; + static const std::string S_MC_AVG_SPEED = "mc_avg_speed"; static const std::string S_LAST_UPDATED = "last_updated"; + static const std::string S_COUNTER = "counter"; static const std::string S_STATUS = "status"; std::string line; @@ -111,7 +114,10 @@ SharedHandle<ServerStat> sstat(new ServerStat(m[S_HOST], m[S_PROTOCOL])); try { sstat->setDownloadSpeed(Util::parseUInt(m[S_DL_SPEED])); + sstat->setSingleConnectionAvgSpeed(Util::parseUInt(m[S_SC_AVG_SPEED])); + sstat->setMultiConnectionAvgSpeed(Util::parseUInt(m[S_MC_AVG_SPEED])); sstat->setLastUpdated(Time(Util::parseInt(m[S_LAST_UPDATED]))); + sstat->setCounter(Util::parseUInt(m[S_COUNTER])); sstat->setStatus(m[S_STATUS]); add(sstat); } catch(RecoverableException* e) { Index: src/prefs.h =================================================================== --- src/prefs.h (revision 51) +++ src/prefs.h (revision 52) @@ -141,10 +141,11 @@ extern const std::string V_NOTICE; extern const std::string V_WARN; extern const std::string V_ERROR; -// value: inorder | feedback +// value: inorder | feedback | adaptive extern const std::string PREF_URI_SELECTOR; extern const std::string V_INORDER; extern const std::string V_FEEDBACK; +extern const std::string V_ADAPTIVE; // value: 1*digit extern const std::string PREF_SERVER_STAT_TIMEOUT; // value: string that your file system recognizes as a file name. Index: src/ServerStatURISelector.cc =================================================================== --- src/ServerStatURISelector.cc (revision 51) +++ src/ServerStatURISelector.cc (revision 52) @@ -57,7 +57,7 @@ } }; -std::string ServerStatURISelector::select(std::deque<std::string>& uris) +std::string ServerStatURISelector::select(std::deque<std::string>& uris, bool reserved) { if(uris.empty()) { return A2STR::NIL; Index: src/InOrderURISelector.h =================================================================== --- src/InOrderURISelector.h (revision 51) +++ src/InOrderURISelector.h (revision 52) @@ -44,7 +44,7 @@ virtual ~InOrderURISelector(); - virtual std::string select(std::deque<std::string>& uris); + virtual std::string select(std::deque<std::string>& uris, bool reserved); }; } // namespace aria2 Index: src/AdaptiveURISelector.cc =================================================================== --- src/AdaptiveURISelector.cc (revision 0) +++ src/AdaptiveURISelector.cc (revision 52) @@ -0,0 +1,242 @@ +/* <!-- copyright */ +/* + * aria2 - The high speed download utility + * + * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2008 Aurelien Lefebvre, Mandriva + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + */ +/* copyright --> */ +#include "AdaptiveURISelector.h" +#include "ServerStatURISelector.h" +#include "URISelector.h" +#include "ServerStatMan.h" +#include "ServerStat.h" +#include "RequestGroup.h" +#include "Request.h" +#include "A2STR.h" +#include "prefs.h" +#include "Option.h" +#include "SimpleRandomizer.h" +#include <cstdlib> +#include <algorithm> +#include <cmath> + +namespace aria2 { + +/* In that URI Selector, select method returns one of the bests + * mirrors for first and reserved connections. For supplementary + * ones, it returns mirrors which has not been tested yet, and + * if each of them already tested, returns mirrors which has to + * be tested again. Otherwise, it doesn't return anymore mirrors. + */ + +AdaptiveURISelector::AdaptiveURISelector +(const SharedHandle<ServerStatMan>& serverStatMan, + const SharedHandle<RequestGroup>& requestGroup): + _serverStatMan(serverStatMan), + _requestGroup(requestGroup), + _counter(0) + { + const Option* op = _requestGroup->getOption(); + _nbServerToEvaluate = op->getAsInt(PREF_METALINK_SERVERS) - 1; + } + +AdaptiveURISelector::~AdaptiveURISelector() {} + +std::string AdaptiveURISelector::select(std::deque<std::string>& uris, bool reserved) +{ + + if(uris.empty()) { + return A2STR::NIL; + } else { + + _counter++; + /* At least, 3 mirrors must be tested */ + if(getNbTestedServers(uris) < 3) { + std::string notTested = getFirstNotTestedUri(uris); + if(notTested != A2STR::NIL) { + --_nbServerToEvaluate; + uris.erase(std::find(uris.begin(), uris.end(), notTested)); + return notTested; + } + } + + if(!reserved && _counter > 1 && _nbServerToEvaluate > 0) { + _nbServerToEvaluate--; + std::string notTested = getFirstNotTestedUri(uris); + if(notTested != A2STR::NIL) { + /* Here we return the first untested mirror */ + uris.erase(std::find(uris.begin(), uris.end(), notTested)); + return notTested; + } + /* Here we return a mirror which need + * to be tested again */ + std::string toTest = getFirstToTestUri(uris); + if(toTest != A2STR::NIL) + uris.erase(std::find(uris.begin(), uris.end(), toTest)); + return toTest; + } + else { + /* Here we return one of the bests mirrors */ + unsigned int max = getMaxDownloadSpeed(uris); + unsigned int min = max-(int)(max*0.25); + std::deque<std::string> bests = getUrisBySpeed(uris, min); + std::string selectedUri; + + if(bests.size() < 2) + selectedUri = getMaxDownloadSpeedUri(uris); + else + selectedUri = selectRandomUri(bests); + + if(selectedUri != A2STR::NIL) { + uris.erase(std::find(uris.begin(), uris.end(), selectedUri)); + return selectedUri; + } + + return A2STR::NIL; + } + } +} + +void AdaptiveURISelector::resetCounters() { + const Option* op = _requestGroup->getOption(); + _counter = 0; + _nbServerToEvaluate = op->getAsInt(PREF_METALINK_SERVERS) - 1; +} + +unsigned int AdaptiveURISelector::getMaxDownloadSpeed(std::deque<std::string>& uris) +{ + std::string uri = getMaxDownloadSpeedUri(uris); + if(uri == A2STR::NIL) + return 0; + SharedHandle<ServerStat> ss = getServerStats(uri); + unsigned int singleConnectionAvgSpeed = ss->getSingleConnectionAvgSpeed(); + unsigned int multiConnectionAvgSpeed = ss->getMultiConnectionAvgSpeed(); + if(singleConnectionAvgSpeed > multiConnectionAvgSpeed) + return singleConnectionAvgSpeed; + return multiConnectionAvgSpeed; +} + +std::string AdaptiveURISelector::getMaxDownloadSpeedUri(std::deque<std::string>& uris) +{ + int max = -1; + std::string uri = A2STR::NIL; + for(std::deque<std::string>::iterator i = uris.begin(); + i != uris.end(); ++i) { + SharedHandle<ServerStat> ss = getServerStats(*i); + if(ss.isNull()) + continue; + + if((int)ss->getSingleConnectionAvgSpeed() > max) { + max = ss->getSingleConnectionAvgSpeed(); + uri = (*i); + } + if((int)ss->getMultiConnectionAvgSpeed() > max) { + max = ss->getMultiConnectionAvgSpeed(); + uri = (*i); + } + } + return uri; +} + +std::deque<std::string> AdaptiveURISelector::getUrisBySpeed(std::deque<std::string>& uris, unsigned int min) +{ + std::deque<std::string> bests; + for(std::deque<std::string>::iterator i = uris.begin(); + i != uris.end(); ++i) { + SharedHandle<ServerStat> ss = getServerStats(*i); + if(ss.isNull()) + continue; + if(ss->getSingleConnectionAvgSpeed() > min || + ss->getMultiConnectionAvgSpeed() > min) { + bests.push_back(*i); + } + } + return bests; +} + +std::string AdaptiveURISelector::selectRandomUri(std::deque<std::string>& uris) +{ + int pos = SimpleRandomizer::getInstance()->getRandomNumber(uris.size()); + std::deque<std::string>::iterator i = uris.begin(); + i = i+pos; + return *i; +} + +std::string AdaptiveURISelector::getFirstNotTestedUri(std::deque<std::string>& uris) +{ + for(std::deque<std::string>::iterator i = uris.begin(); + i != uris.end(); ++i) { + SharedHandle<ServerStat> ss = getServerStats(*i); + if(ss.isNull()) + return *i; + } + return A2STR::NIL; +} + +std::string AdaptiveURISelector::getFirstToTestUri(std::deque<std::string>& uris) { + unsigned int counter; + int power; + for(std::deque<std::string>::iterator i = uris.begin(); + i != uris.end(); ++i) { + SharedHandle<ServerStat> ss = getServerStats(*i); + if(ss.isNull()) + continue; + counter = ss->getCounter(); + if(counter > 8) + continue; + power = (int)pow(2.0, (float)counter); + /* We test the mirror another time if it has not been + * tested since 2^counter days */ + if(ss->getLastUpdated().difference() > power*24*60*60) { + return *i; + } + } + return A2STR::NIL; +} + +SharedHandle<ServerStat> AdaptiveURISelector::getServerStats(std::string uri) { + Request r; + r.setUrl(uri); + return _serverStatMan->find(r.getHost(), r.getProtocol()); +} + +unsigned int AdaptiveURISelector::getNbTestedServers(std::deque<std::string>& uris) { + unsigned int counter = 0; + for(std::deque<std::string>::iterator i = uris.begin(); + i != uris.end(); ++i) { + SharedHandle<ServerStat> ss = getServerStats(*i); + if(ss.isNull()) + counter++; + } + return uris.size() - counter; +} + +} // namespace aria2 Index: src/ServerStat.h =================================================================== --- src/ServerStat.h (revision 51) +++ src/ServerStat.h (revision 52) @@ -75,6 +75,18 @@ // set download speed. This method doesn't update _lastUpdate. void setDownloadSpeed(unsigned int downloadSpeed); + unsigned int getSingleConnectionAvgSpeed() const; + void updateSingleConnectionAvgSpeed(unsigned int downloadSpeed); + void setSingleConnectionAvgSpeed(unsigned int singleConnectionAvgSpeed); + + unsigned int getMultiConnectionAvgSpeed() const; + void updateMultiConnectionAvgSpeed(unsigned int downloadSpeed); + void setMultiConnectionAvgSpeed(unsigned int singleConnectionAvgSpeed); + + unsigned int getCounter() const; + void increaseCounter(); + void setCounter(unsigned int value); + // This method doesn't update _lastUpdate. void setStatus(STATUS status); @@ -104,7 +116,13 @@ std::string _protocol; unsigned int _downloadSpeed; + + unsigned int _singleConnectionAvgSpeed; + + unsigned int _multiConnectionAvgSpeed; + unsigned int _counter; + STATUS _status; Time _lastUpdated; Index: src/Makefile.am =================================================================== --- src/Makefile.am (revision 51) +++ src/Makefile.am (revision 52) @@ -191,6 +191,7 @@ ServerStat.cc ServerStat.h\ ServerStatMan.cc ServerStatMan.h\ URISelector.h\ + AdaptiveURISelector.cc AdaptiveURISelector.h\ InOrderURISelector.cc InOrderURISelector.h\ ServerStatURISelector.cc ServerStatURISelector.h\ NsCookieParser.cc NsCookieParser.h\ @@ -486,4 +487,4 @@ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@ @LIBEXPAT_CPPFLAGS@\ @LIBZ_CPPFLAGS@ @SQLITE3_CPPFLAGS@\ - -DLOCALEDIR=\"$(localedir)\" @DEFS@ #-pg \ No newline at end of file + -DLOCALEDIR=\"$(localedir)\" @DEFS@ #-pg Index: src/ServerStatURISelector.h =================================================================== --- src/ServerStatURISelector.h (revision 51) +++ src/ServerStatURISelector.h (revision 52) @@ -50,7 +50,7 @@ virtual ~ServerStatURISelector(); - virtual std::string select(std::deque<std::string>& uris); + virtual std::string select(std::deque<std::string>& uris, bool reserved); }; } // namespace aria2 Index: src/ServerStat.cc =================================================================== --- src/ServerStat.cc (revision 51) +++ src/ServerStat.cc (revision 52) @@ -49,6 +49,9 @@ _hostname(hostname), _protocol(protocol), _downloadSpeed(0), + _singleConnectionAvgSpeed(0), + _multiConnectionAvgSpeed(0), + _counter(0), _status(OK) {} ServerStat::~ServerStat() {} @@ -92,6 +95,75 @@ _lastUpdated.reset(); } +unsigned int ServerStat::getSingleConnectionAvgSpeed() const +{ + return _singleConnectionAvgSpeed; +} + +void ServerStat::setSingleConnectionAvgSpeed(unsigned int singleConnectionAvgSpeed) +{ + _singleConnectionAvgSpeed = singleConnectionAvgSpeed; +} + +void ServerStat::updateSingleConnectionAvgSpeed(unsigned int downloadSpeed) +{ + float avgDownloadSpeed; + if(_counter == 0) + return; + if(_counter < 5) { + avgDownloadSpeed = ((((float)_counter-1)/(float)_counter)*(float)_singleConnectionAvgSpeed) + + ((1.0/(float)_counter)*(float)downloadSpeed); + } + else { + avgDownloadSpeed = ((4.0/5.0)*(float)_singleConnectionAvgSpeed) + + ((1.0/5.0)*(float)downloadSpeed); + } + if(avgDownloadSpeed < (int)(0.80*_singleConnectionAvgSpeed)) + _counter = 0; + _singleConnectionAvgSpeed = (int)avgDownloadSpeed; +} + +unsigned int ServerStat::getMultiConnectionAvgSpeed() const +{ + return _multiConnectionAvgSpeed; +} + +void ServerStat::setMultiConnectionAvgSpeed(unsigned int multiConnectionAvgSpeed) +{ + _multiConnectionAvgSpeed = multiConnectionAvgSpeed; +} + +void ServerStat::updateMultiConnectionAvgSpeed(unsigned int downloadSpeed) +{ + float avgDownloadSpeed; + if(_counter == 0) + return; + if(_counter < 5) { + avgDownloadSpeed = ((((float)_counter-1)/(float)_counter)*(float)_multiConnectionAvgSpeed) + + ((1.0/(float)_counter)*(float)downloadSpeed); + } + else { + avgDownloadSpeed = ((4.0/5.0)*(float)_multiConnectionAvgSpeed) + + ((1.0/5.0)*(float)downloadSpeed); + } + _multiConnectionAvgSpeed = (int)avgDownloadSpeed; +} + +unsigned int ServerStat::getCounter() const +{ + return _counter; +} + +void ServerStat::increaseCounter() +{ + _counter++; +} + +void ServerStat::setCounter(unsigned int value) +{ + _counter = value; +} + void ServerStat::setStatus(STATUS status) { _status = status; @@ -160,7 +232,10 @@ o << "host=" << serverStat.getHostname() << ", " << "protocol=" << serverStat.getProtocol() << ", " << "dl_speed=" << serverStat.getDownloadSpeed() << ", " + << "sc_avg_speed=" << serverStat.getSingleConnectionAvgSpeed() << ", " + << "mc_avg_speed=" << serverStat.getMultiConnectionAvgSpeed() << ", " << "last_updated=" << serverStat.getLastUpdated().getTime() << ", " + << "counter=" << serverStat.getCounter() << ", " << "status=" << ServerStat::STATUS_STRING[serverStat.getStatus()]; return o; } Index: src/Makefile.in =================================================================== --- src/Makefile.in (revision 51) +++ src/Makefile.in (revision 52) @@ -411,6 +411,7 @@ Decoder.h ChunkedDecoder.cc ChunkedDecoder.h Signature.cc \ Signature.h ServerStat.cc ServerStat.h ServerStatMan.cc \ ServerStatMan.h URISelector.h InOrderURISelector.cc \ + AdaptiveURISelector.h AdaptiveURISelector.cc \ InOrderURISelector.h ServerStatURISelector.cc \ ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \ CookieStorage.cc CookieStorage.h SocketBuffer.cc \ @@ -807,6 +808,7 @@ RarestPieceSelector.$(OBJEXT) ChunkedDecoder.$(OBJEXT) \ Signature.$(OBJEXT) ServerStat.$(OBJEXT) \ ServerStatMan.$(OBJEXT) InOrderURISelector.$(OBJEXT) \ + AdaptiveURISelector.$(OBJEXT) \ ServerStatURISelector.$(OBJEXT) NsCookieParser.$(OBJEXT) \ CookieStorage.$(OBJEXT) SocketBuffer.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ @@ -1135,6 +1137,7 @@ Decoder.h ChunkedDecoder.cc ChunkedDecoder.h Signature.cc \ Signature.h ServerStat.cc ServerStat.h ServerStatMan.cc \ ServerStatMan.h URISelector.h InOrderURISelector.cc \ + AdaptiveURISelector.h AdaptiveURISelector.cc \ InOrderURISelector.h ServerStatURISelector.cc \ ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \ CookieStorage.cc CookieStorage.h SocketBuffer.cc \ @@ -1242,6 +1245,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractProxyResponseCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractSingleDiskAdaptor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActivePeerConnectionCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AdaptiveURISelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceList.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AsyncNameResolver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfig.Po@am__quote@ Index: src/AdaptiveURISelector.h =================================================================== --- src/AdaptiveURISelector.h (revision 0) +++ src/AdaptiveURISelector.h (revision 52) @@ -0,0 +1,73 @@ +/* <!-- copyright */ +/* + * aria2 - The high speed download utility + * + * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2008 Aurelien Lefebvre, Mandriva + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + */ +/* copyright --> */ +#ifndef _D_ADAPTIVE_URI_SELECTOR_H_ +#define _D_ADAPTIVE_URI_SELECTOR_H_ +#include "URISelector.h" +#include "SharedHandle.h" +#include "ServerStatMan.h" +#include "RequestGroup.h" +#include "ServerStat.h" + +namespace aria2 { + +class AdaptiveURISelector:public URISelector { +private: + SharedHandle<ServerStatMan> _serverStatMan; + SharedHandle<RequestGroup> _requestGroup; + unsigned int _nbServerToEvaluate; + unsigned int _counter; + + unsigned int getMaxDownloadSpeed(std::deque<std::string>& uris); + std::string getMaxDownloadSpeedUri(std::deque<std::string>& uris); + std::deque<std::string> getUrisBySpeed(std::deque<std::string>& uris, unsigned int min); + std::string selectRandomUri(std::deque<std::string>& uris); + std::string getFirstNotTestedUri(std::deque<std::string>& uris); + std::string getFirstToTestUri(std::deque<std::string>& uris); + SharedHandle<ServerStat> getServerStats(std::string uri); + unsigned int getNbTestedServers(std::deque<std::string>& uris); +public: + AdaptiveURISelector(const SharedHandle<ServerStatMan>& serverStatMan, + const SharedHandle<RequestGroup>& requestGroup); + + virtual ~AdaptiveURISelector(); + + virtual std::string select(std::deque<std::string>& uris, bool reserved); + + virtual void resetCounters(); +}; + +} // namespace aria2 +#endif // _D_ADAPTIVE_URI_SELECTOR_H_ Property changes on: src/AdaptiveURISelector.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/RequestGroup.h =================================================================== --- src/RequestGroup.h (revision 51) +++ src/RequestGroup.h (revision 52) @@ -156,7 +156,7 @@ void createNextCommand(std::deque<Command*>& commands, DownloadEngine* e, unsigned int numCommand, - const std::string& method = "GET"); + bool reserved, const std::string& method = "GET"); void addURI(const std::string& uri) { Index: src/prefs.cc =================================================================== --- src/prefs.cc (revision 51) +++ src/prefs.cc (revision 52) @@ -137,10 +137,11 @@ const std::string V_NOTICE("notice"); const std::string V_WARN("warn"); const std::string V_ERROR("error"); -// value: inorder | feedback +// value: inorder | feedback | adaptive const std::string PREF_URI_SELECTOR("uri-selector"); const std::string V_INORDER("inorder"); const std::string V_FEEDBACK("feedback"); +const std::string V_ADAPTIVE("adaptive"); // value: 1*digit const std::string PREF_SERVER_STAT_TIMEOUT("server-stat-timeout"); // value: string that your file system recognizes as a file name.