From 20cb0173574453fdd216c4a7ac317490302c16d1 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 27 May 2008 15:07:39 +0000
Subject: [PATCH] 2008-05-28  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot
 com>

	Refactored broken outstanding piece handling.
	* src/DefaultPieceStorage.cc
	* src/DefaultPieceStorage.h
	* src/Piece.cc
	* src/Piece.h
---
 ChangeLog                  |   8 +++
 src/DefaultPieceStorage.cc | 116 ++++++++++++++++++-------------------
 src/DefaultPieceStorage.h  |   4 +-
 src/Piece.cc               |   5 ++
 src/Piece.h                |   2 +
 5 files changed, 72 insertions(+), 63 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2b6c15ec..bbdb1377 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-05-28  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Refactored broken outstanding piece handling.
+	* src/DefaultPieceStorage.cc
+	* src/DefaultPieceStorage.h
+	* src/Piece.cc
+	* src/Piece.h
+
 2008-05-27  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Fixed compile error on Mac OS X 10.3.9. This error was caused by the
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index ec0ee4f9..a45bdde5 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -143,29 +143,24 @@ PieceHandle DefaultPieceStorage::getPiece(size_t index)
 
 void DefaultPieceStorage::addUsedPiece(const PieceHandle& piece)
 {
-  usedPieces.push_back(piece);
+  std::deque<SharedHandle<Piece> >::iterator i =
+    std::lower_bound(usedPieces.begin(), usedPieces.end(), piece);
+  usedPieces.insert(i, piece);
+  logger->debug("usedPieces.size()=%zu", usedPieces.size());
 }
 
-class FindPiece {
-private:
-  size_t index;
-public:
-  FindPiece(size_t index):index(index) {}
-
-  bool operator()(const PieceHandle& piece) {
-    return piece->getIndex() == index;
-  }
-};
-
 PieceHandle DefaultPieceStorage::findUsedPiece(size_t index) const
 {
-  Pieces::const_iterator itr = std::find_if(usedPieces.begin(),
-					    usedPieces.end(),
-					    FindPiece(index));
-  if(itr == usedPieces.end()) {
-    return SharedHandle<Piece>();
+  SharedHandle<Piece> p(new Piece());
+  p->setIndex(index);
+
+  std::deque<SharedHandle<Piece> >::const_iterator i =
+    std::lower_bound(usedPieces.begin(), usedPieces.end(), p);
+  if(i != usedPieces.end() && (*i) == p) {
+    return *i;
   } else {
-    return *itr;
+    p.reset(0);
+    return p;
   }
 }
 
@@ -237,50 +232,48 @@ void DefaultPieceStorage::deleteUsedPiece(const PieceHandle& piece)
   if(piece.isNull()) {
     return;
   }
-  Pieces::iterator itr = std::find(usedPieces.begin(), usedPieces.end(), piece);
-  if(itr != usedPieces.end()) {
-    usedPieces.erase(itr);
+  std::deque<SharedHandle<Piece> >::iterator i = 
+    std::lower_bound(usedPieces.begin(), usedPieces.end(), piece);
+  if(i != usedPieces.end() && (*i) == piece) {
+    usedPieces.erase(i);
   }
 }
 
-void DefaultPieceStorage::reduceUsedPieces(size_t delMax)
-{
-  if(usedPieces.size() <= delMax) {
-    return;
-  }
-  size_t toDelete = usedPieces.size()-delMax;
-  int fillRate = 10;
-  while(fillRate < 50) {
-    size_t deleted = deleteUsedPiecesByFillRate(fillRate, toDelete);
-    if(deleted == 0) {
-      break;
-    }
-    toDelete -= deleted;
-    fillRate += 10;
-  }
-}
+// void DefaultPieceStorage::reduceUsedPieces(size_t upperBound)
+// {
+//   size_t usedPiecesSize = usedPieces.size();
+//   if(usedPiecesSize <= upperBound) {
+//     return;
+//   }
+//   size_t delNum = usedPiecesSize-upperBound;
+//   int fillRate = 10;
+//   while(delNum && fillRate <= 15) {
+//     delNum -= deleteUsedPiecesByFillRate(fillRate, delNum);
+//     fillRate += 5;
+//   }
+// }
 
-size_t DefaultPieceStorage::deleteUsedPiecesByFillRate(int fillRate,
-						       size_t toDelete)
-{
-  size_t deleted = 0;
-  for(Pieces::iterator itr = usedPieces.begin();
-      itr != usedPieces.end() && deleted < toDelete;) {
-    PieceHandle& piece = *itr;
-    if(!bitfieldMan->isUseBitSet(piece->getIndex()) &&
-       piece->countCompleteBlock() <= piece->countBlock()*(fillRate/100.0)) {
-      logger->debug(MSG_DELETING_USED_PIECE,
-		    piece->getIndex(),
-		    (piece->countCompleteBlock()*100)/piece->countBlock(),
-		    fillRate);
-      itr = usedPieces.erase(itr);
-      deleted++;
-    } else {
-      itr++;
-    }
-  }
-  return deleted;
-}
+// size_t DefaultPieceStorage::deleteUsedPiecesByFillRate(int fillRate,
+// 						       size_t delNum)
+// {
+//   size_t deleted = 0;
+//   for(Pieces::iterator itr = usedPieces.begin();
+//       itr != usedPieces.end() && deleted < delNum;) {
+//     PieceHandle& piece = *itr;
+//     if(!bitfieldMan->isUseBitSet(piece->getIndex()) &&
+//        piece->countCompleteBlock() <= piece->countBlock()*(fillRate/100.0)) {
+//       logger->info(MSG_DELETING_USED_PIECE,
+// 		    piece->getIndex(),
+// 		    (piece->countCompleteBlock()*100)/piece->countBlock(),
+// 		    fillRate);
+//       itr = usedPieces.erase(itr);
+//       ++deleted;
+//     } else {
+//       ++itr;
+//     }
+//   }
+//   return deleted;
+// }
 
 void DefaultPieceStorage::completePiece(const PieceHandle& piece)
 {
@@ -288,9 +281,9 @@ void DefaultPieceStorage::completePiece(const PieceHandle& piece)
     return;
   }
   deleteUsedPiece(piece);
-  if(!isEndGame()) {
-    reduceUsedPieces(100);
-  }
+//   if(!isEndGame()) {
+//     reduceUsedPieces(100);
+//   }
   if(allDownloadFinished()) {
     return;
   }
@@ -571,6 +564,7 @@ void DefaultPieceStorage::markPieceMissing(size_t index)
 void DefaultPieceStorage::addInFlightPiece(const Pieces& pieces)
 {
   usedPieces.insert(usedPieces.end(), pieces.begin(), pieces.end());
+  std::sort(usedPieces.begin(), usedPieces.end());
 }
 
 size_t DefaultPieceStorage::countInFlightPiece()
diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h
index a457df44..95e5ce8b 100644
--- a/src/DefaultPieceStorage.h
+++ b/src/DefaultPieceStorage.h
@@ -86,8 +86,8 @@ private:
   bool getMissingPieceIndex(size_t& index, const SharedHandle<Peer>& peer);
   bool getMissingFastPieceIndex(size_t& index, const SharedHandle<Peer>& peer);
   SharedHandle<Piece> checkOutPiece(size_t index);
-  size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete);
-  void reduceUsedPieces(size_t delMax);
+//   size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete);
+//   void reduceUsedPieces(size_t upperBound);
   void deleteUsedPiece(const SharedHandle<Piece>& piece);
   SharedHandle<Piece> findUsedPiece(size_t index) const;
 
diff --git a/src/Piece.cc b/src/Piece.cc
index f35520a3..45537009 100644
--- a/src/Piece.cc
+++ b/src/Piece.cc
@@ -82,6 +82,11 @@ bool Piece::operator==(const Piece& piece) const
   return index == piece.index;
 }
 
+bool Piece::operator<(const Piece& piece) const
+{
+  return index < piece.index;
+}
+
 void Piece::completeBlock(size_t blockIndex) {
   bitfield->setBit(blockIndex);
   bitfield->unsetUseBit(blockIndex);
diff --git a/src/Piece.h b/src/Piece.h
index c978f451..cd52e3e6 100644
--- a/src/Piece.h
+++ b/src/Piece.h
@@ -67,6 +67,8 @@ public:
   
   bool operator==(const Piece& piece) const;
 
+  bool operator<(const Piece& piece) const;
+
   bool getMissingUnusedBlockIndex(size_t& index) const;
   bool getMissingBlockIndex(size_t& index) const;
   bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;