Преглед изворни кода

2009-01-18 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Added --bt-max-peers option to specify the maximum number of
	peers per torrent. 0 means unlimited number of peers.
	* src/ActivePeerConnectionCommand.cc
	* src/BtRuntime.h
	* src/DefaultPeerStorage.cc
	* src/DefaultPeerStorage.h
	* src/OptionHandlerFactory.cc
	* src/RequestGroup.cc
	* src/option_processing.cc
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
	* test/DefaultPeerStorageTest.cc
Tatsuhiro Tsujikawa пре 16 година
родитељ
комит
ca2567f2a2

+ 16 - 0
ChangeLog

@@ -1,3 +1,19 @@
+2009-01-18  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Added --bt-max-peers option to specify the maximum number of peers
+	per torrent. 0 means unlimited number of peers.
+	* src/ActivePeerConnectionCommand.cc
+	* src/BtRuntime.h
+	* src/DefaultPeerStorage.cc
+	* src/DefaultPeerStorage.h
+	* src/OptionHandlerFactory.cc
+	* src/RequestGroup.cc
+	* src/option_processing.cc
+	* src/prefs.cc
+	* src/prefs.h
+	* src/usage_text.h
+	* test/DefaultPeerStorageTest.cc
+
 2009-01-18  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Added --bt-hash-check-seed option.  If true is given to this

+ 12 - 4
src/ActivePeerConnectionCommand.cc

@@ -90,10 +90,18 @@ bool ActivePeerConnectionCommand::execute() {
        (!_pieceStorage->downloadFinished() &&
 	(tstat.getDownloadSpeed() < _thresholdSpeed ||
 	 _btRuntime->lessThanMinPeers()))) {
-      unsigned int numConnection = _pieceStorage->downloadFinished() ?
-	std::min(_numNewConnection,
-		 BtRuntime::MAX_PEERS-_btRuntime->getConnections()) :
-	_numNewConnection;
+
+      unsigned int numConnection = 0;
+      if(_pieceStorage->downloadFinished()) {
+	if(_btRuntime->getMaxPeers() > _btRuntime->getConnections()) {
+	  numConnection =
+	    std::min(_numNewConnection,
+		     _btRuntime->getMaxPeers()-_btRuntime->getConnections());
+	}
+      } else {
+	numConnection = _numNewConnection;
+      }
+
       for(unsigned int numAdd = numConnection;
 	  numAdd > 0 && _peerStorage->isPeerAvailable(); --numAdd) {
 	PeerHandle peer = _peerStorage->getUnusedPeer();

+ 37 - 6
src/BtRuntime.h

@@ -47,8 +47,14 @@ private:
   bool halt;
   unsigned int connections;
   bool _ready;
+  // Maximum number of peers to hold connections at the same time.
+  // 0 means unlimited.
+  unsigned int _maxPeers;
+  // Minimum number of peers. This value is used for getting more peers from
+  // tracker. 0 means always the number of peers is under minimum.
+  unsigned int _minPeers;
 
-  static const unsigned int MIN_PEERS = 40;
+  static const unsigned int DEFAULT_MIN_PEERS = 40;
 
 public:
   BtRuntime():
@@ -56,7 +62,9 @@ public:
     port(0),
     halt(false),
     connections(0),
-    _ready(false)
+    _ready(false),
+    _maxPeers(DEFAULT_MAX_PEERS),
+    _minPeers(DEFAULT_MIN_PEERS)
   {}
 
   ~BtRuntime() {}
@@ -87,17 +95,40 @@ public:
 
   void decreaseConnections() { connections--; }
 
-  bool lessThanMaxPeers() const { return connections < MAX_PEERS; }
+  bool lessThanMaxPeers() const
+  {
+    return _maxPeers == 0 || connections < _maxPeers;
+  }
 
-  bool lessThanMinPeers() const { return connections < MIN_PEERS; }
+  bool lessThanMinPeers() const
+  {
+    return _minPeers == 0 || connections < _minPeers;
+  }
 
-  bool lessThanEqMinPeers() const { return connections <= MIN_PEERS; }
+  bool lessThanEqMinPeers() const
+  {
+    return _minPeers == 0 || connections <= _minPeers;
+  }
 
   bool ready() { return _ready; }
 
   void setReady(bool go) { _ready = go; }
 
-  static const unsigned int MAX_PEERS = 55;
+  void setMaxPeers(unsigned int maxPeers)
+  {
+    _maxPeers = maxPeers;
+    _minPeers = maxPeers*0.8;
+    if(_minPeers == 0 && maxPeers != 0) {
+      _minPeers = maxPeers;
+    }
+  }
+
+  unsigned int getMaxPeers() const
+  {
+    return _maxPeers;
+  }
+
+  static const unsigned int DEFAULT_MAX_PEERS = 55;
 };
 
 typedef SharedHandle<BtRuntime> BtRuntimeHandle;

+ 13 - 1
src/DefaultPeerStorage.cc

@@ -49,12 +49,13 @@
 
 namespace aria2 {
 
+static const int MAX_PEER_LIST_SIZE = 1024;
+
 DefaultPeerStorage::DefaultPeerStorage(const BtContextHandle& btContext,
 				       const Option* option):
   btContext(btContext),
   option(option),
   logger(LogFactory::getInstance()),
-  maxPeerListSize(BtRuntime::MAX_PEERS+(BtRuntime::MAX_PEERS >> 2)),
   removedPeerSessionDownloadLength(0),
   removedPeerSessionUploadLength(0),
   _seederStateChoke(new BtSeederStateChoke()),
@@ -84,11 +85,22 @@ bool DefaultPeerStorage::isPeerAlreadyAdded(const PeerHandle& peer)
   return std::find_if(peers.begin(), peers.end(), FindIdenticalPeer(peer)) != peers.end();
 }
 
+static size_t calculateMaxPeerListSize(const SharedHandle<BtRuntime>& btRuntime)
+{
+  if(btRuntime.isNull()) {
+    return MAX_PEER_LIST_SIZE;
+  }
+  return btRuntime->getMaxPeers() == 0 ?
+    MAX_PEER_LIST_SIZE :
+    btRuntime->getMaxPeers()+(btRuntime->getMaxPeers() >> 2);
+}
+
 bool DefaultPeerStorage::addPeer(const PeerHandle& peer) {
   if(isPeerAlreadyAdded(peer)) {
     logger->debug("Adding %s:%u is rejected because it has been already added.", peer->ipaddr.c_str(), peer->port);
     return false;
   }
+  size_t maxPeerListSize = calculateMaxPeerListSize(_btRuntime);
   if(peers.size() >= maxPeerListSize) {
     deleteUnusedPeer(peers.size()-maxPeerListSize+1);
   }

+ 0 - 5
src/DefaultPeerStorage.h

@@ -55,7 +55,6 @@ private:
   const Option* option;
   std::deque<SharedHandle<Peer> > peers;
   Logger* logger;
-  size_t maxPeerListSize;
   uint64_t removedPeerSessionDownloadLength;
   uint64_t removedPeerSessionUploadLength;
 
@@ -93,10 +92,6 @@ public:
 
   virtual void executeChoke();
 
-  void setMaxPeerListSize(size_t size) { this->maxPeerListSize = size; }
- 
-  size_t getMaxPeerListSize() const { return maxPeerListSize; }
-
   void deleteUnusedPeer(size_t delSize);
   
   void onErasingPeer(const SharedHandle<Peer>& peer);

+ 10 - 0
src/OptionHandlerFactory.cc

@@ -735,6 +735,16 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_BITTORRENT);
     handlers.push_back(op);
   }
+  {
+    SharedHandle<OptionHandler> op(new NumberOptionHandler
+				   (PREF_BT_MAX_PEERS,
+				    TEXT_BT_MAX_PEERS,
+				    "55",
+				    0));
+    op->addTag(TAG_BITTORRENT);
+    handlers.push_back(op);
+				   
+  }
   {
     SharedHandle<OptionHandler> op(new ParameterOptionHandler
 				   (PREF_BT_MIN_CRYPTO_LEVEL,

+ 1 - 0
src/RequestGroup.cc

@@ -231,6 +231,7 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
   
       BtRuntimeHandle btRuntime(new BtRuntime());
       btRuntime->setListenPort(_option->getAsInt(PREF_LISTEN_PORT));
+      btRuntime->setMaxPeers(_option->getAsInt(PREF_BT_MAX_PEERS));
       btRegistry->registerBtRuntime(btContext->getInfoHashAsString(),
 				    btRuntime);
       _btRuntime = btRuntime;

+ 4 - 0
src/option_processing.cc

@@ -219,6 +219,7 @@ Option* option_processing(int argc, char* const argv[])
       { PREF_DHT_FILE_PATH.c_str(), required_argument, &lopt, 35 },
       { PREF_MAX_OVERALL_UPLOAD_LIMIT.c_str(), required_argument, &lopt, 36 },
       { PREF_BT_HASH_CHECK_SEED.c_str(), optional_argument, &lopt, 37 },
+      { PREF_BT_MAX_PEERS.c_str(), required_argument, &lopt, 38 },
 #endif // ENABLE_BITTORRENT
 #ifdef ENABLE_METALINK
       { PREF_METALINK_FILE.c_str(), required_argument, NULL, 'M' },
@@ -349,6 +350,9 @@ Option* option_processing(int argc, char* const argv[])
       case 37:
 	cmdstream << PREF_BT_HASH_CHECK_SEED << "=" << optarg << "\n";
 	break;
+      case 38:
+	cmdstream << PREF_BT_MAX_PEERS << "=" << optarg << "\n";
+	break;
       case 100:
 	cmdstream << PREF_METALINK_VERSION << "=" << optarg << "\n";
 	break;

+ 2 - 0
src/prefs.cc

@@ -271,6 +271,8 @@ const std::string PREF_BT_MAX_OPEN_FILES("bt-max-open-files");
 const std::string PREF_BT_SEED_UNVERIFIED("bt-seed-unverified");
 // values: true | false
 const std::string PREF_BT_HASH_CHECK_SEED("bt-hash-check-seed");
+// values: 1*digit
+const std::string PREF_BT_MAX_PEERS("bt-max-peers");
 
 /**
  * Metalink related preferences

+ 2 - 0
src/prefs.h

@@ -275,6 +275,8 @@ extern const std::string PREF_BT_MAX_OPEN_FILES;
 extern const std::string PREF_BT_SEED_UNVERIFIED;
 // values: true | false
 extern const std::string PREF_BT_HASH_CHECK_SEED;
+// values: 1*digit
+extern const std::string PREF_BT_MAX_PEERS;
 
 /**
  * Metalink related preferences

+ 4 - 0
src/usage_text.h

@@ -305,6 +305,10 @@ _(" --bt-max-open-files=NUM      Specify maximum number of files to open in each
 #define TEXT_BT_SEED_UNVERIFIED \
 _(" --bt-seed-unverified[=true|false] Seed previously downloaded files without\n"\
   "                              verifying piece hashes.")
+#define TEXT_BT_MAX_PEERS \
+_(" --bt-max-peers=NUM           Specify the maximum number of peers per torrent.\n"\
+  "                              0 means unlimited.\n"\
+  "                              See also --bt-request-peer-speed-limit option.")
 #define TEXT_METALINK_FILE \
 _(" -M, --metalink-file=METALINK_FILE The file path to the .metalink file.")
 #define TEXT_METALINK_SERVERS \

+ 3 - 2
test/DefaultPeerStorageTest.cc

@@ -97,6 +97,9 @@ void DefaultPeerStorageTest::testDeleteUnusedPeer() {
 
 void DefaultPeerStorageTest::testAddPeer() {
   DefaultPeerStorage ps(btContext, option);
+  SharedHandle<BtRuntime> btRuntime(new BtRuntime());
+  btRuntime->setMaxPeers(3);
+  ps.setBtRuntime(btRuntime);
 
   SharedHandle<Peer> peer1(new Peer("192.168.0.1", 6889));
   SharedHandle<Peer> peer2(new Peer("192.168.0.2", 6889));
@@ -113,8 +116,6 @@ void DefaultPeerStorageTest::testAddPeer() {
   // the number of peers doesn't change.
   CPPUNIT_ASSERT_EQUAL((size_t)3, ps.countPeer());
 
-  ps.setMaxPeerListSize(3);
-
   SharedHandle<Peer> peer4(new Peer("192.168.0.4", 6889));
 
   peer1->usedBy(1);