Browse Source

2009-05-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Selecting files are now done in
	DefaultBtContext::setFileFileter().
	PieceStorage::setFileFilter(), DiskAdaptor::addDownloadEntry()
	functions are removed because they are no longer used.  Creating
	filter in BitfieldMan is done in new funtion
	PieceStorage::setupFileFilter()	
	* src/BtContext.cc
	* src/BtContext.h
	* src/DefaultBtContext.cc
	* src/DefaultBtContext.h
	* src/DefaultPieceStorage.cc
	* src/DefaultPieceStorage.h
	* src/DiskAdaptor.cc
	* src/DiskAdaptor.h
	* src/PieceStorage.h
	* src/RequestGroup.cc
	* src/UnknownLengthPieceStorage.h
	* src/XmlRpcMethodImpl.cc
	* test/DefaultBtContextTest.cc
	* test/MockBtContext.h
	* test/MockPieceStorage.h
Tatsuhiro Tsujikawa 16 years ago
parent
commit
2758562eb0

+ 24 - 0
ChangeLog

@@ -1,3 +1,27 @@
+2009-05-12  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Selecting files are now done in
+	DefaultBtContext::setFileFileter().
+	PieceStorage::setFileFilter(), DiskAdaptor::addDownloadEntry()
+	functions are removed because they are no longer used.  Creating
+	filter in BitfieldMan is done in new funtion
+	PieceStorage::setupFileFilter()	
+	* src/BtContext.cc
+	* src/BtContext.h
+	* src/DefaultBtContext.cc
+	* src/DefaultBtContext.h
+	* src/DefaultPieceStorage.cc
+	* src/DefaultPieceStorage.h
+	* src/DiskAdaptor.cc
+	* src/DiskAdaptor.h
+	* src/PieceStorage.h
+	* src/RequestGroup.cc
+	* src/UnknownLengthPieceStorage.h
+	* src/XmlRpcMethodImpl.cc
+	* test/DefaultBtContextTest.cc
+	* test/MockBtContext.h
+	* test/MockPieceStorage.h
+
 2009-05-10  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Fixed compile error on Mac OS X

+ 0 - 10
src/BtContext.cc

@@ -62,14 +62,4 @@ const std::string BtContext::C_ANNOUNCE_LIST("announce-list");
 
 const std::string BtContext::C_NODES("nodes");
 
-void BtContext::setFileFilter(const IntSequence& seq)
-{
-  _fileFilter = seq;
-}
-
-IntSequence BtContext::getFileFilter() const
-{
-  return _fileFilter;
-}
-
 } // namespace aria2

+ 2 - 5
src/BtContext.h

@@ -36,6 +36,7 @@
 #define _D_BT_CONTEXT_H_
 
 #include "DownloadContext.h"
+
 #include <utility>
 #include <deque>
 
@@ -49,8 +50,6 @@ class RequestGroup;
 class BtContext:public DownloadContext {
 protected:
   bool _private;
-
-  IntSequence _fileFilter;
 public:
   BtContext():_private(false) {}
   
@@ -87,9 +86,7 @@ public:
 
   virtual const std::string& getName() const = 0;
 
-  void setFileFilter(const IntSequence& seq);
-
-  IntSequence getFileFilter() const;
+  virtual void setFileFilter(IntSequence seq) = 0;
 
   static const std::string C_NAME;
 

+ 18 - 0
src/DefaultBtContext.cc

@@ -514,4 +514,22 @@ void DefaultBtContext::setFilePathWithIndex
   }
 }
 
+void DefaultBtContext::setFileFilter(IntSequence seq)
+{
+  std::deque<int32_t> fileIndexes = seq.flush();
+  std::sort(fileIndexes.begin(), fileIndexes.end());
+  fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()),
+		    fileIndexes.end());
+
+  bool selectAll = fileIndexes.empty() || fileEntries.size() == 1;
+    
+  int32_t index = 1;
+  for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+	fileEntries.begin(); i != fileEntries.end(); ++i, ++index) {
+    (*i)->setRequested
+      (selectAll ||
+       std::binary_search(fileIndexes.begin(), fileIndexes.end(), index));
+  }
+}
+
 } // namespace aria2

+ 4 - 0
src/DefaultBtContext.h

@@ -39,6 +39,8 @@
 
 #include <iosfwd>
 
+#include "IntSequence.h"
+
 namespace aria2 {
 
 class Randomizer;
@@ -160,6 +162,8 @@ private:
 
   virtual std::deque<std::pair<std::string, uint16_t> >& getNodes();
 
+  virtual void setFileFilter(IntSequence seq);
+
   std::string generatePeerId() const;
 
   void setPeerIdPrefix(const std::string& peerIdPrefix)

+ 17 - 34
src/DefaultPieceStorage.cc

@@ -358,12 +358,6 @@ bool DefaultPieceStorage::isSelectiveDownloadingMode()
   return bitfieldMan->isFilterEnabled();
 }
 
-void DefaultPieceStorage::finishSelectiveDownloadingMode()
-{
-  bitfieldMan->clearFilter();
-  diskAdaptor->addAllDownloadEntry();
-}
-
 // not unittested
 void DefaultPieceStorage::cancelPiece(const PieceHandle& piece)
 {
@@ -420,45 +414,34 @@ size_t DefaultPieceStorage::getInFlightPieceCompletedLength() const
 }
 
 // not unittested
-void DefaultPieceStorage::setFileFilter(const std::deque<std::string>& filePaths)
-{
-  if(downloadContext->getFileMode() != DownloadContext::MULTI || filePaths.empty()) {
+void DefaultPieceStorage::setupFileFilter()
+{
+  std::deque<SharedHandle<FileEntry> > fileEntries =
+    downloadContext->getFileEntries();
+  bool allSelected = true;
+  for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+	fileEntries.begin(); i != fileEntries.end(); ++i) {
+    if(!(*i)->isRequested()) {
+      allSelected = false;
+      break;
+    }
+  }
+  if(allSelected) {
     return;
   }
-  diskAdaptor->removeAllDownloadEntry();
-  for(std::deque<std::string>::const_iterator pitr = filePaths.begin();
-      pitr != filePaths.end(); pitr++) {
-    if(!diskAdaptor->addDownloadEntry(*pitr)) {
-      throw DlAbortEx(StringFormat(EX_NO_SUCH_FILE_ENTRY, (*pitr).c_str()).str());
+  for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+	fileEntries.begin(); i != fileEntries.end(); ++i) {
+    if((*i)->isRequested()) {
+      bitfieldMan->addFilter((*i)->getOffset(), (*i)->getLength());
     }
-    FileEntryHandle fileEntry = diskAdaptor->getFileEntryFromPath(*pitr);
-    bitfieldMan->addFilter(fileEntry->getOffset(), fileEntry->getLength());
   }
   bitfieldMan->enableFilter();
 }
 
-void DefaultPieceStorage::setFileFilter(IntSequence seq)
-{
-  std::deque<int32_t> fileIndexes = seq.flush();
-  std::sort(fileIndexes.begin(), fileIndexes.end());
-  fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()), fileIndexes.end());
-  std::deque<std::string> filePaths;
-  const FileEntries& entries = diskAdaptor->getFileEntries();
-  int32_t entriesSize = entries.size();
-  for(int32_t i = 0; i < entriesSize; i++) {
-    if(std::binary_search(fileIndexes.begin(), fileIndexes.end(), i+1)) {
-      logger->debug("index=%d is %s", i+1, entries[i]->getPath().c_str());
-      filePaths.push_back(entries[i]->getPath());
-    }
-  }
-  setFileFilter(filePaths);
-}
-
 // not unittested
 void DefaultPieceStorage::clearFileFilter()
 {
   bitfieldMan->clearFilter();
-  diskAdaptor->addAllDownloadEntry();
 }
 
 // not unittested

+ 2 - 6
src/DefaultPieceStorage.h

@@ -151,10 +151,8 @@ public:
 
   virtual void initStorage();
 
-  virtual void setFileFilter(const std::deque<std::string>& filePaths);
-
-  virtual void setFileFilter(IntSequence seq);
-
+  virtual void setupFileFilter();
+  
   virtual void clearFileFilter();
 
   virtual bool downloadFinished();
@@ -178,8 +176,6 @@ public:
 
   virtual bool isSelectiveDownloadingMode();
 
-  virtual void finishSelectiveDownloadingMode();
-
   virtual bool isEndGame();
   
   virtual SharedHandle<DiskAdaptor> getDiskAdaptor();

+ 0 - 51
src/DiskAdaptor.cc

@@ -36,9 +36,6 @@
 #include "FileEntry.h"
 #include "LogFactory.h"
 #include "Logger.h"
-#include "message.h"
-#include "DlAbortEx.h"
-#include "StringFormat.h"
 
 namespace aria2 {
 
@@ -50,54 +47,6 @@ DiskAdaptor::DiskAdaptor():
 
 DiskAdaptor::~DiskAdaptor() {}
 
-FileEntryHandle DiskAdaptor::getFileEntryFromPath(const std::string& fileEntryPath) const
-{
-  for(FileEntries::const_iterator itr = fileEntries.begin();
-      itr != fileEntries.end(); itr++) {
-    if((*itr)->getPath() == fileEntryPath) {
-      return *itr;
-    }
-  }
-  throw DlAbortEx(StringFormat(EX_NO_SUCH_FILE_ENTRY, fileEntryPath.c_str()).str());
-}
-
-bool DiskAdaptor::addDownloadEntry(const std::string& fileEntryPath)
-{
-  for(FileEntries::iterator itr = fileEntries.begin();
-      itr != fileEntries.end(); itr++) {
-    if((*itr)->getPath() == fileEntryPath) {
-      (*itr)->setRequested(true);
-      return true;
-    }
-  }
-  return false;
-}
-
-bool DiskAdaptor::addDownloadEntry(size_t index)
-{
-  if(fileEntries.size() <= index) {
-    return false;
-  }
-  fileEntries[index]->setRequested(true);
-  return true;
-}
-
-void DiskAdaptor::addAllDownloadEntry()
-{
-  for(FileEntries::iterator itr = fileEntries.begin();
-      itr != fileEntries.end(); itr++) {
-    (*itr)->setRequested(true);
-  }
-}
-
-void DiskAdaptor::removeAllDownloadEntry()
-{
-  for(FileEntries::iterator itr = fileEntries.begin();
-      itr != fileEntries.end(); itr++) {
-    (*itr)->setRequested(false);
-  }
-}
-
 void DiskAdaptor::setFileEntries(const FileEntries& fileEntries) {
   this->fileEntries = fileEntries;
 }

+ 3 - 11
src/DiskAdaptor.h

@@ -36,10 +36,12 @@
 #define _D_DISK_ADAPTOR_H_
 
 #include "BinaryStream.h"
-#include "TimeA2.h"
+
 #include <string>
 #include <deque>
 
+#include "TimeA2.h"
+
 namespace aria2 {
 
 class FileEntry;
@@ -73,18 +75,8 @@ public:
 
   void setFileEntries(const std::deque<SharedHandle<FileEntry> >& fileEntries);
 
-  SharedHandle<FileEntry> getFileEntryFromPath(const std::string& fileEntryPath) const;
-
   const std::deque<SharedHandle<FileEntry> >& getFileEntries() const;
 
-  bool addDownloadEntry(const std::string& fileEntryPath);
-
-  bool addDownloadEntry(size_t index);
-
-  void addAllDownloadEntry();
-
-  void removeAllDownloadEntry();
-
   virtual SharedHandle<FileAllocationIterator> fileAllocationIterator() = 0;
 
   virtual void enableDirectIO() {}

+ 2 - 6
src/PieceStorage.h

@@ -142,11 +142,9 @@ public:
   virtual uint64_t getCompletedLength() = 0;
 
   virtual uint64_t getFilteredCompletedLength() = 0;
-  
-  virtual void setFileFilter(const std::deque<std::string>& filePaths) = 0;
-
-  virtual void setFileFilter(IntSequence seq) = 0;
 
+  virtual void setupFileFilter() = 0;
+  
   virtual void clearFileFilter() = 0;
   
   /**
@@ -177,8 +175,6 @@ public:
 
   virtual bool isSelectiveDownloadingMode() = 0;
 
-  virtual void finishSelectiveDownloadingMode() = 0;
-
   virtual bool isEndGame() = 0;
 
   virtual SharedHandle<DiskAdaptor> getDiskAdaptor() = 0;

+ 1 - 1
src/RequestGroup.cc

@@ -230,7 +230,7 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
 	_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
 	_uris.clear();
 
-	_pieceStorage->setFileFilter(btContext->getFileFilter());
+	_pieceStorage->setupFileFilter();
       } else if(btContext->getFileEntries().size() == 1) {
 	// web-seeding is only enabled for single file torrent
 	SharedHandle<FileEntry> fileEntry = btContext->getFileEntries().front();

+ 1 - 5
src/UnknownLengthPieceStorage.h

@@ -152,9 +152,7 @@ public:
     return getCompletedLength();
   }
   
-  virtual void setFileFilter(const std::deque<std::string>& filePaths) {}
-
-  virtual void setFileFilter(IntSequence seq) {}
+  virtual void setupFileFilter() {}
 
   virtual void clearFileFilter() {}
   
@@ -201,8 +199,6 @@ public:
     return false;
   }
 
-  virtual void finishSelectiveDownloadingMode() {}
-
   virtual bool isEndGame()
   {
     return false;

+ 8 - 30
src/XmlRpcMethodImpl.cc

@@ -265,38 +265,16 @@ BDE GetFilesXmlRpcMethod::process
       (StringFormat("No file data is available for GID#%d", gid).str());
   }
   BDE files = BDE::list();
-  SharedHandle<BtContext> btctx =
-    dynamic_pointer_cast<BtContext>(group->getDownloadContext());
-  if(btctx.isNull()) {
+  std::deque<SharedHandle<FileEntry> > fileEntries =
+    group->getDownloadContext()->getFileEntries();
+  size_t index = 1;
+  for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+	fileEntries.begin(); i != fileEntries.end(); ++i, ++index) {
     BDE entry = BDE::dict();
-    entry["index"] = BDE("1");
-    entry["path"] = group->getDownloadContext()->getActualBasePath();
-    entry["selected"] = BDE("true");
+    entry["index"] = Util::uitos(index);
+    entry["path"] = (*i)->getPath();
+    entry["selected"] = (*i)->isRequested()?BDE("true"):BDE("false");
     files << entry;
-  } else {
-    std::deque<int32_t> fileIndexes = btctx->getFileFilter().flush();
-    std::sort(fileIndexes.begin(), fileIndexes.end());
-    fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()),
-		      fileIndexes.end());
-    std::deque<SharedHandle<FileEntry> > fileEntries =
-      btctx->getFileEntries();
-
-    bool selectAll = fileIndexes.empty() || fileEntries.size() == 1;
-    
-    int32_t index = 1;
-    for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
-	  fileEntries.begin(); i != fileEntries.end(); ++i, ++index) {
-      BDE entry = BDE::dict();
-      entry["index"] = Util::itos(index);
-      entry["path"] = (*i)->getPath();
-      if(selectAll ||
-	 std::binary_search(fileIndexes.begin(), fileIndexes.end(), index)) {
-	entry["selected"] = BDE("true");
-      } else {
-	entry["selected"] = BDE("false");
-      }
-      files << entry;
-    }
   }
   BDE resParams = BDE::list();
   resParams << files;

+ 48 - 0
test/DefaultBtContextTest.cc

@@ -44,6 +44,8 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testLoadFromMemory_joinPathSingle);
   CPPUNIT_TEST(testGetNodes);
   CPPUNIT_TEST(testGetActualBasePath);
+  CPPUNIT_TEST(testSetFileFilter_single);
+  CPPUNIT_TEST(testSetFileFilter_multi);
   CPPUNIT_TEST_SUITE_END();
 public:
   void setUp() {
@@ -76,6 +78,8 @@ public:
   void testLoadFromMemory_joinPathSingle();
   void testGetNodes();
   void testGetActualBasePath();
+  void testSetFileFilter_single();
+  void testSetFileFilter_multi();
 };
 
 
@@ -548,4 +552,48 @@ void DefaultBtContextTest::testGetActualBasePath()
 		       multiCtx.getActualBasePath());
 }
 
+void DefaultBtContextTest::testSetFileFilter_single()
+{
+  DefaultBtContext ctx;
+  ctx.load("single.torrent");
+
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange(""));
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange("1"));
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+
+  // For single file torrent, file is always selected whatever range
+  // is passed.
+  ctx.setFileFilter(Util::parseIntRange("2"));
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+}
+
+void DefaultBtContextTest::testSetFileFilter_multi()
+{
+  DefaultBtContext ctx;
+  ctx.load("test.torrent");
+
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+  CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange(""));
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+  CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange("2"));
+  CPPUNIT_ASSERT(!ctx.getFileEntries()[0]->isRequested());
+  CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange("3"));
+  CPPUNIT_ASSERT(!ctx.getFileEntries()[0]->isRequested());
+  CPPUNIT_ASSERT(!ctx.getFileEntries()[1]->isRequested());
+
+  ctx.setFileFilter(Util::parseIntRange("1,2"));
+  CPPUNIT_ASSERT(ctx.getFileEntries()[0]->isRequested());
+  CPPUNIT_ASSERT(ctx.getFileEntries()[1]->isRequested());
+}
+
 } // namespace aria2

+ 1 - 0
test/MockBtContext.h

@@ -170,6 +170,7 @@ public:
     _nodes = nodes;
   }
 
+  virtual void setFileFilter(IntSequence seq) {}
 };
 
 } // namespace aria2

+ 1 - 5
test/MockPieceStorage.h

@@ -121,9 +121,7 @@ public:
     this->filteredCompletedLength = completedLength;
   }
   
-  virtual void setFileFilter(const std::deque<std::string>& filePaths) {}
-
-  virtual void setFileFilter(IntSequence seq) {}
+  virtual void setupFileFilter() {}
 
   virtual void clearFileFilter() {}
 
@@ -167,8 +165,6 @@ public:
     this->selectiveDownloadingMode = flag;
   }
 
-  virtual void finishSelectiveDownloadingMode() {}
-
   virtual bool isEndGame() {
     return endGame;
   }