Browse Source

2008-05-31 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Reduced the usage of gettimeofday().
	* src/DefaultBtMessageDispatcher.cc
	
(DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing)
	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
	* src/RequestSlot.cc
	* src/RequestSlot.h
	(RequestSlot::isTimeout)
	
	Made RequestSlot have a reference to Piece object to avoid find
	Piece repeatedly.
	* src/DefaultBtMessageDispatcher.cc
	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
	* src/RequestSlot.cc
	* src/RequestSlot.h
	(RequestSlot::getPiece)
	* test/DefaultBtMessageDispatcherTest.cc
Tatsuhiro Tsujikawa 17 years ago
parent
commit
1d7b5e6f4a
5 changed files with 73 additions and 21 deletions
  1. 19 0
      ChangeLog
  2. 17 8
      src/DefaultBtMessageDispatcher.cc
  3. 14 5
      src/RequestSlot.cc
  4. 17 2
      src/RequestSlot.h
  5. 6 6
      test/DefaultBtMessageDispatcherTest.cc

+ 19 - 0
ChangeLog

@@ -1,3 +1,22 @@
+2008-05-31  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Reduced the usage of gettimeofday().
+	* src/DefaultBtMessageDispatcher.cc
+	(DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing)
+	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
+	* src/RequestSlot.cc
+	* src/RequestSlot.h
+	(RequestSlot::isTimeout)
+	
+	Made RequestSlot have a reference to Piece object to avoid find
+	Piece repeatedly.
+	* src/DefaultBtMessageDispatcher.cc
+	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
+	* src/RequestSlot.cc
+	* src/RequestSlot.h
+	(RequestSlot::getPiece)
+	* test/DefaultBtMessageDispatcherTest.cc
+
 2008-05-31  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	* src/TimeA2.cc

+ 17 - 8
src/DefaultBtMessageDispatcher.cc

@@ -246,6 +246,7 @@ private:
   SharedHandle<PieceStorage> _pieceStorage;
   BtMessageDispatcher* _messageDispatcher;
   WeakHandle<BtMessageFactory> _messageFactory;
+  const struct timeval& _now;
   time_t _requestTimeout;
   Logger* _logger;
 public:
@@ -253,26 +254,27 @@ public:
 			  const SharedHandle<PieceStorage>& pieceStorage,
 			  BtMessageDispatcher* dispatcher,
 			  const WeakHandle<BtMessageFactory>& factory,
+			  const struct timeval& now,
 			  time_t requestTimeout):
     _cuid(cuid),
     _peer(peer),
     _pieceStorage(pieceStorage),
     _messageDispatcher(dispatcher),
     _messageFactory(factory),
+    _now(now),
     _requestTimeout(requestTimeout),
     _logger(LogFactory::getInstance()) {}
 
   void operator()(const RequestSlot& slot)
   {
-    SharedHandle<Piece> piece = _pieceStorage->getPiece(slot.getIndex());
-    if(slot.isTimeout(_requestTimeout)) {
+    if(slot.isTimeout(_now, _requestTimeout)) {
       _logger->debug(MSG_DELETING_REQUEST_SLOT_TIMEOUT,
 		     _cuid,
 		     slot.getBlockIndex());
       _logger->debug("index=%d, begin=%d", slot.getIndex(), slot.getBegin());
-      piece->cancelBlock(slot.getBlockIndex());
+      slot.getPiece()->cancelBlock(slot.getBlockIndex());
       _peer->snubbing(true);
-    } else if(piece->hasBlock(slot.getBlockIndex())) {
+    } else if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
       _logger->debug(MSG_DELETING_REQUEST_SLOT_ACQUIRED,
 		     _cuid,
 		     slot.getBlockIndex());
@@ -288,20 +290,22 @@ public:
 class FindStaleRequestSlot {
 private:
   SharedHandle<PieceStorage> _pieceStorage;
+  const struct timeval& _now;
   time_t _requestTimeout;
 public:
   FindStaleRequestSlot(const SharedHandle<PieceStorage>& pieceStorage,
+		       const struct timeval& now,
 		       time_t requestTimeout):
     _pieceStorage(pieceStorage),
+    _now(now),
     _requestTimeout(requestTimeout) {}
 
   bool operator()(const RequestSlot& slot)
   {
-    if(slot.isTimeout(_requestTimeout)) {
+    if(slot.isTimeout(_now, _requestTimeout)) {
       return true;
     } else {
-      SharedHandle<Piece> piece = _pieceStorage->getPiece(slot.getIndex());
-      if(piece->hasBlock(slot.getBlockIndex())) {
+      if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
 	return true;
       } else {
 	return false;
@@ -312,15 +316,20 @@ public:
 
 void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing()
 {
+  struct timeval now;
+  gettimeofday(&now, 0);
+
   std::for_each(requestSlots.begin(), requestSlots.end(),
 		ProcessStaleRequestSlot(cuid,
 					peer,
 					pieceStorage,
 					this,
 					messageFactory,
+					now,
 					requestTimeout));
   requestSlots.erase(std::remove_if(requestSlots.begin(), requestSlots.end(),
 				    FindStaleRequestSlot(pieceStorage,
+							 now,
 							 requestTimeout)),
 		     requestSlots.end());
 }
@@ -363,7 +372,7 @@ bool DefaultBtMessageDispatcher::isOutstandingRequest(size_t index, size_t block
 RequestSlot
 DefaultBtMessageDispatcher::getOutstandingRequest(size_t index, uint32_t begin, size_t length)
 {
-  RequestSlot ret(0, 0, 0, 0);
+  RequestSlot ret;
   RequestSlot rs(index, begin, length, 0);
   std::deque<RequestSlot>::iterator i =
     std::lower_bound(requestSlots.begin(), requestSlots.end(), rs);

+ 14 - 5
src/RequestSlot.cc

@@ -37,21 +37,25 @@
 
 namespace aria2 {
 
-RequestSlot RequestSlot::nullSlot(0, 0, 0, 0);
+RequestSlot RequestSlot::nullSlot = RequestSlot();
 
-RequestSlot::RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex)
-  :index(index), begin(begin), length(length), blockIndex(blockIndex) {}
+RequestSlot::RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex, const SharedHandle<Piece>& piece)
+  :index(index), begin(begin), length(length), blockIndex(blockIndex),
+   _piece(piece) {}
 
 RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
   copy(requestSlot);
 }
 
+RequestSlot::RequestSlot():index(0), begin(0), length(0), blockIndex(0) {}
+
 void RequestSlot::copy(const RequestSlot& requestSlot) {
   index = requestSlot.index;
   begin = requestSlot.begin;
   length = requestSlot.length;
   blockIndex = requestSlot.blockIndex;
   dispatchedTime = requestSlot.dispatchedTime;
+  _piece = requestSlot._piece;
 }
 
 RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot)
@@ -89,8 +93,8 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
   dispatchedTime.setTimeInSec(secFromEpoch);
 }
 
-bool RequestSlot::isTimeout(time_t timeoutSec) const {
-  return dispatchedTime.elapsed(timeoutSec);
+bool RequestSlot::isTimeout(const struct timeval& now, time_t timeoutSec) const {
+  return dispatchedTime.difference(now) >= timeoutSec;
 }
 
 unsigned int RequestSlot::getLatencyInMillis() const {
@@ -102,4 +106,9 @@ bool RequestSlot::isNull(const RequestSlot& requestSlot) {
     requestSlot.length == 0;
 }
 
+SharedHandle<Piece> RequestSlot::getPiece() const
+{
+  return _piece;
+}
+
 } // namespace aria2

+ 17 - 2
src/RequestSlot.h

@@ -37,6 +37,7 @@
 
 #include "common.h"
 #include "TimeA2.h"
+#include "Piece.h"
 #include <deque>
 
 namespace aria2 {
@@ -48,11 +49,23 @@ private:
   uint32_t begin;
   size_t length;
   size_t blockIndex;
+
+  // This is the piece whose index is index of this RequestSlot has.
+  // To detect duplicate RequestSlot, we have to find the piece using
+  // PieceStorage::getPiece() repeatedly. It turns out that this process
+  // takes time(about 1.7% of processing time). To reduce it, we put piece here
+  // at the construction of RequestSlot as a cache.
+  SharedHandle<Piece> _piece;
+
   void copy(const RequestSlot& requestSlot);
 public:
-  RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex);
+  RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex,
+	      const SharedHandle<Piece>& piece = SharedHandle<Piece>());
+
   RequestSlot(const RequestSlot& requestSlot);
 
+  RequestSlot();
+
   ~RequestSlot() {}
 
   RequestSlot& operator=(const RequestSlot& requestSlot);
@@ -66,7 +79,7 @@ public:
   void setDispatchedTime();
   void setDispatchedTime(time_t secFromEpoch);
 
-  bool isTimeout(time_t timeoutSec) const;
+  bool isTimeout(const struct timeval& now, time_t timeoutSec) const;
   unsigned int getLatencyInMillis() const;
 
   size_t getIndex() const { return index; }
@@ -81,6 +94,8 @@ public:
   size_t getBlockIndex() const { return blockIndex; }
   void setBlockIndex(size_t blockIndex) { this->blockIndex = blockIndex; }
 
+  SharedHandle<Piece> getPiece() const;
+
   static RequestSlot nullSlot;
 
   static bool isNull(const RequestSlot& requestSlot);

+ 6 - 6
test/DefaultBtMessageDispatcherTest.cc

@@ -278,9 +278,9 @@ void DefaultBtMessageDispatcherTest::testDoCancelSendingPieceAction() {
 int MY_PIECE_LENGTH = 16*1024;
 
 void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
-  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
-  
   SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
+  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
+  
   size_t index;
   CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
   CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@@ -305,11 +305,11 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
 }
 
 void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_timeout() {
-  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
+  SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
+  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
   // make this slot timeout
   slot.setDispatchedTime(0);
 
-  SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
   size_t index;
   CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
   CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@@ -338,11 +338,11 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_tim
 }
 
 void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_completeBlock() {
-  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
-  
   SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
   piece->completeBlock(0);
 
+  RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
+  
   SharedHandle<MockPieceStorage2> pieceStorage(new MockPieceStorage2());
   pieceStorage->setPiece(piece);
   BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),