Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 251a5265d601cd9b2d84ecdf5b73a2d4 > files > 2

aria2-0.15.3-0.20080918.1mdv2009.0.src.rpm

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.