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
pull/1/head
Tatsuhiro Tsujikawa 2009-05-12 13:31:04 +00:00
parent c3129fd4a4
commit 2758562eb0
16 changed files with 131 additions and 163 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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)
void DefaultPieceStorage::setupFileFilter()
{
if(downloadContext->getFileMode() != DownloadContext::MULTI || filePaths.empty()) {
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

View File

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

View File

@ -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;
}

View File

@ -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() {}

View File

@ -143,9 +143,7 @@ public:
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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

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

View File

@ -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;
}