mirror of https://github.com/aria2/aria2
2009-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed broken selected file BitTorrent download. * src/MultiDiskWriter.cc * test/MultiDiskWriterTest.cc * test/MultiFileAllocationIteratorTest.ccpull/1/head
parent
4570a4242e
commit
b5af788a00
|
@ -1,3 +1,10 @@
|
||||||
|
2009-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Fixed broken selected file BitTorrent download.
|
||||||
|
* src/MultiDiskWriter.cc
|
||||||
|
* test/MultiDiskWriterTest.cc
|
||||||
|
* test/MultiFileAllocationIteratorTest.cc
|
||||||
|
|
||||||
2009-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2009-02-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Fixed #define guard for EpollEventPoll
|
Fixed #define guard for EpollEventPoll
|
||||||
|
|
|
@ -34,8 +34,9 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "MultiDiskAdaptor.h"
|
#include "MultiDiskAdaptor.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "DefaultDiskWriter.h"
|
#include "DefaultDiskWriter.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
@ -196,18 +197,22 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
|
||||||
(createDiskWriterEntry(*i, (*i)->isRequested()));
|
(createDiskWriterEntry(*i, (*i)->isRequested()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, bool> dwreq;
|
||||||
|
|
||||||
// TODO Currently, pieceLength == 0 is used for unit testing only.
|
// TODO Currently, pieceLength == 0 is used for unit testing only.
|
||||||
if(pieceLength > 0) {
|
if(pieceLength > 0) {
|
||||||
std::deque<SharedHandle<DiskWriterEntry> >::iterator done =
|
std::deque<SharedHandle<DiskWriterEntry> >::iterator done =
|
||||||
diskWriterEntries.begin();
|
diskWriterEntries.begin();
|
||||||
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator itr =
|
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator itr =
|
||||||
diskWriterEntries.begin(); itr != diskWriterEntries.end();) {
|
diskWriterEntries.begin(); itr != diskWriterEntries.end();) {
|
||||||
if(!(*itr)->getFileEntry()->isRequested()) {
|
const SharedHandle<FileEntry>& fileEntry = (*itr)->getFileEntry();
|
||||||
|
|
||||||
|
if(!fileEntry->isRequested()) {
|
||||||
++itr;
|
++itr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
off_t pieceStartOffset =
|
off_t pieceStartOffset =
|
||||||
((*itr)->getFileEntry()->getOffset()/pieceLength)*pieceLength;
|
(fileEntry->getOffset()/pieceLength)*pieceLength;
|
||||||
if(itr != diskWriterEntries.begin()) {
|
if(itr != diskWriterEntries.begin()) {
|
||||||
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
|
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
|
||||||
itr-1; true; --i) {
|
itr-1; true; --i) {
|
||||||
|
@ -225,24 +230,45 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++itr;
|
if(fileEntry->getLength() > 0) {
|
||||||
|
off_t lastPieceStartOffset =
|
||||||
|
(fileEntry->getOffset()+fileEntry->getLength()-1)/pieceLength*pieceLength;
|
||||||
|
logger->debug("Checking adjacent backward file to %s"
|
||||||
|
" whose lastPieceStartOffset+pieceLength=%lld",
|
||||||
|
fileEntry->getPath().c_str(),
|
||||||
|
lastPieceStartOffset+pieceLength);
|
||||||
|
|
||||||
|
++itr;
|
||||||
|
// adjacent backward files are not needed to be allocated. They
|
||||||
|
// just requre DiskWriter
|
||||||
|
for(; itr != diskWriterEntries.end() &&
|
||||||
|
!(*itr)->getFileEntry()->isRequested(); ++itr) {
|
||||||
|
logger->debug("file=%s, offset=%lld",
|
||||||
|
(*itr)->getFileEntry()->getPath().c_str(),
|
||||||
|
(*itr)->getFileEntry()->getOffset());
|
||||||
|
|
||||||
for(; itr != diskWriterEntries.end(); ++itr) {
|
|
||||||
if((*itr)->getFileEntry()->getOffset() <
|
if((*itr)->getFileEntry()->getOffset() <
|
||||||
static_cast<off_t>(pieceStartOffset+pieceLength)) {
|
static_cast<off_t>(lastPieceStartOffset+pieceLength)) {
|
||||||
(*itr)->needsFileAllocation(true);
|
logger->debug("%s needs diskwriter",
|
||||||
|
(*itr)->getFileEntry()->getPath().c_str());
|
||||||
|
dwreq[(*itr)->getFileEntry()->getPath()] = true;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done = itr-1;
|
done = itr-1;
|
||||||
|
} else {
|
||||||
|
done = itr;
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultDiskWriterFactory dwFactory;
|
DefaultDiskWriterFactory dwFactory;
|
||||||
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
|
for(std::deque<SharedHandle<DiskWriterEntry> >::iterator i =
|
||||||
diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) {
|
diskWriterEntries.begin(); i != diskWriterEntries.end(); ++i) {
|
||||||
if((*i)->needsFileAllocation() || (*i)->fileExists(getTopDirPath())) {
|
if((*i)->needsFileAllocation() ||
|
||||||
|
dwreq.find((*i)->getFileEntry()->getPath()) != dwreq.end() ||
|
||||||
|
(*i)->fileExists(getTopDirPath())) {
|
||||||
logger->debug("Creating DiskWriter for filename=%s",
|
logger->debug("Creating DiskWriter for filename=%s",
|
||||||
(*i)->getFilePath(getTopDirPath()).c_str());
|
(*i)->getFilePath(getTopDirPath()).c_str());
|
||||||
(*i)->setDiskWriter(dwFactory.newDiskWriter());
|
(*i)->setDiskWriter(dwFactory.newDiskWriter());
|
||||||
|
|
|
@ -48,13 +48,22 @@ CPPUNIT_TEST_SUITE_REGISTRATION( MultiDiskAdaptorTest );
|
||||||
|
|
||||||
std::deque<SharedHandle<FileEntry> > createEntries() {
|
std::deque<SharedHandle<FileEntry> > createEntries() {
|
||||||
SharedHandle<FileEntry> array[] = {
|
SharedHandle<FileEntry> array[] = {
|
||||||
SharedHandle<FileEntry>(new FileEntry("file1.txt", 0, 0)),
|
SharedHandle<FileEntry>(new FileEntry("file0.txt", 0, 0)),
|
||||||
SharedHandle<FileEntry>(new FileEntry("file2.txt", 15, 0)),
|
SharedHandle<FileEntry>(new FileEntry("file1.txt", 15, 0)),
|
||||||
SharedHandle<FileEntry>(new FileEntry("file3.txt", 7, 15)),
|
SharedHandle<FileEntry>(new FileEntry("file2.txt", 7, 15)),
|
||||||
SharedHandle<FileEntry>(new FileEntry("file4.txt", 0, 22)),
|
SharedHandle<FileEntry>(new FileEntry("file3.txt", 0, 22)),
|
||||||
SharedHandle<FileEntry>(new FileEntry("file5.txt", 2, 22)),
|
SharedHandle<FileEntry>(new FileEntry("file4.txt", 2, 22)),
|
||||||
SharedHandle<FileEntry>(new FileEntry("file6.txt", 0, 24)),
|
SharedHandle<FileEntry>(new FileEntry("file5.txt", 0, 24)),
|
||||||
};
|
};
|
||||||
|
// 1 1 2 2
|
||||||
|
// 0....5....0....5....0....5
|
||||||
|
// ++--++--++--++--++--++--++
|
||||||
|
// | file0
|
||||||
|
// *************** file1
|
||||||
|
// ******* file2
|
||||||
|
// | file3
|
||||||
|
// ** flie4
|
||||||
|
// | file5
|
||||||
std::deque<SharedHandle<FileEntry> > entries(&array[0],
|
std::deque<SharedHandle<FileEntry> > entries(&array[0],
|
||||||
&array[arrayLength(array)]);
|
&array[arrayLength(array)]);
|
||||||
for(std::deque<SharedHandle<FileEntry> >::const_iterator i = entries.begin();
|
for(std::deque<SharedHandle<FileEntry> >::const_iterator i = entries.begin();
|
||||||
|
@ -115,6 +124,7 @@ void MultiDiskAdaptorTest::testResetDiskWriterEntries()
|
||||||
CPPUNIT_ASSERT(entries[0]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(entries[0]->getDiskWriter().isNull());
|
||||||
// Because entries[2] spans entries[1]
|
// Because entries[2] spans entries[1]
|
||||||
CPPUNIT_ASSERT(!entries[1]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[1]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[1]->needsFileAllocation());
|
||||||
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
||||||
|
@ -136,6 +146,7 @@ void MultiDiskAdaptorTest::testResetDiskWriterEntries()
|
||||||
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
||||||
// Because entries[4] spans entries[3]
|
// Because entries[4] spans entries[3]
|
||||||
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[3]->needsFileAllocation());
|
||||||
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[5]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[5]->getDiskWriter().isNull());
|
||||||
|
|
||||||
|
@ -154,8 +165,8 @@ void MultiDiskAdaptorTest::testResetDiskWriterEntries()
|
||||||
CPPUNIT_ASSERT(!entries[1]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[1]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[3]->getDiskWriter().isNull());
|
||||||
// Because entries[3] spans entries[4]
|
// entries[3] is 0 length. No overrap with entries[4]
|
||||||
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(entries[4]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(!entries[5]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[5]->getDiskWriter().isNull());
|
||||||
|
|
||||||
adaptor->closeFile();
|
adaptor->closeFile();
|
||||||
|
@ -195,6 +206,44 @@ void MultiDiskAdaptorTest::testResetDiskWriterEntries()
|
||||||
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[4]->getDiskWriter().isNull());
|
||||||
CPPUNIT_ASSERT(entries[5]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(entries[5]->getDiskWriter().isNull());
|
||||||
|
|
||||||
|
adaptor->closeFile();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::deque<SharedHandle<FileEntry> > fileEntries = createEntries();
|
||||||
|
for(size_t i = 1; i < 6; ++i) {
|
||||||
|
fileEntries[i]->setRequested(false);
|
||||||
|
}
|
||||||
|
adaptor->setFileEntries(fileEntries);
|
||||||
|
adaptor->openFile();
|
||||||
|
std::deque<SharedHandle<DiskWriterEntry> > entries =
|
||||||
|
adaptor->getDiskWriterEntries();
|
||||||
|
CPPUNIT_ASSERT(!entries[0]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[1]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[2]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[3]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[4]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[5]->getDiskWriter().isNull());
|
||||||
|
|
||||||
|
adaptor->closeFile();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::deque<SharedHandle<FileEntry> > fileEntries = createEntries();
|
||||||
|
for(size_t i = 2; i < 6; ++i) {
|
||||||
|
fileEntries[i]->setRequested(false);
|
||||||
|
}
|
||||||
|
adaptor->setFileEntries(fileEntries);
|
||||||
|
adaptor->openFile();
|
||||||
|
std::deque<SharedHandle<DiskWriterEntry> > entries =
|
||||||
|
adaptor->getDiskWriterEntries();
|
||||||
|
CPPUNIT_ASSERT(!entries[0]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(!entries[1]->getDiskWriter().isNull());
|
||||||
|
// entries[1] spans entries[2]
|
||||||
|
CPPUNIT_ASSERT(!entries[2]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(!entries[2]->needsFileAllocation());
|
||||||
|
CPPUNIT_ASSERT(entries[3]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[4]->getDiskWriter().isNull());
|
||||||
|
CPPUNIT_ASSERT(entries[5]->getDiskWriter().isNull());
|
||||||
|
|
||||||
adaptor->closeFile();
|
adaptor->closeFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,9 +269,9 @@ void MultiDiskAdaptorTest::testWriteData() {
|
||||||
adaptor->writeData((const unsigned char*)msg.c_str(), msg.size(), 0);
|
adaptor->writeData((const unsigned char*)msg.c_str(), msg.size(), 0);
|
||||||
adaptor->closeFile();
|
adaptor->closeFile();
|
||||||
|
|
||||||
CPPUNIT_ASSERT(File("file1.txt").isFile());
|
CPPUNIT_ASSERT(File("file0.txt").isFile());
|
||||||
char buf[128];
|
char buf[128];
|
||||||
readFile("file2.txt", buf, 5);
|
readFile("file1.txt", buf, 5);
|
||||||
buf[5] = '\0';
|
buf[5] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(msg, std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(msg, std::string(buf));
|
||||||
|
|
||||||
|
@ -231,10 +280,10 @@ void MultiDiskAdaptorTest::testWriteData() {
|
||||||
adaptor->writeData((const unsigned char*)msg2.c_str(), msg2.size(), 5);
|
adaptor->writeData((const unsigned char*)msg2.c_str(), msg2.size(), 5);
|
||||||
adaptor->closeFile();
|
adaptor->closeFile();
|
||||||
|
|
||||||
readFile("file2.txt", buf, 15);
|
readFile("file1.txt", buf, 15);
|
||||||
buf[15] = '\0';
|
buf[15] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("1234567890ABCDE"), std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(std::string("1234567890ABCDE"), std::string(buf));
|
||||||
readFile("file3.txt", buf, 1);
|
readFile("file2.txt", buf, 1);
|
||||||
buf[1] = '\0';
|
buf[1] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("F"), std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(std::string("F"), std::string(buf));
|
||||||
|
|
||||||
|
@ -243,20 +292,20 @@ void MultiDiskAdaptorTest::testWriteData() {
|
||||||
adaptor->writeData((const unsigned char*)msg3.c_str(), msg3.size(), 10);
|
adaptor->writeData((const unsigned char*)msg3.c_str(), msg3.size(), 10);
|
||||||
adaptor->closeFile();
|
adaptor->closeFile();
|
||||||
|
|
||||||
readFile("file2.txt", buf, 15);
|
readFile("file1.txt", buf, 15);
|
||||||
buf[15] = '\0';
|
buf[15] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("123456789012345"), std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(std::string("123456789012345"), std::string(buf));
|
||||||
readFile("file3.txt", buf, 7);
|
readFile("file2.txt", buf, 7);
|
||||||
buf[7] = '\0';
|
buf[7] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("1234567"), std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(std::string("1234567"), std::string(buf));
|
||||||
|
|
||||||
CPPUNIT_ASSERT(File("file4.txt").isFile());
|
CPPUNIT_ASSERT(File("file3.txt").isFile());
|
||||||
|
|
||||||
readFile("file5.txt", buf, 2);
|
readFile("file4.txt", buf, 2);
|
||||||
buf[2] = '\0';
|
buf[2] = '\0';
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("12"), std::string(buf));
|
CPPUNIT_ASSERT_EQUAL(std::string("12"), std::string(buf));
|
||||||
|
|
||||||
CPPUNIT_ASSERT(File("file6.txt").isFile());
|
CPPUNIT_ASSERT(File("file5.txt").isFile());
|
||||||
|
|
||||||
} catch(Exception& e) {
|
} catch(Exception& e) {
|
||||||
CPPUNIT_FAIL(e.stackTrace());
|
CPPUNIT_FAIL(e.stackTrace());
|
||||||
|
|
|
@ -120,7 +120,7 @@ void MultiFileAllocationIteratorTest::testMakeDiskWriterEntries()
|
||||||
// file9
|
// file9
|
||||||
CPPUNIT_ASSERT_EQUAL(prefix+std::string("/file9"),
|
CPPUNIT_ASSERT_EQUAL(prefix+std::string("/file9"),
|
||||||
entries[8]->getFilePath(prefix));
|
entries[8]->getFilePath(prefix));
|
||||||
CPPUNIT_ASSERT(entries[8]->needsFileAllocation());
|
CPPUNIT_ASSERT(!entries[8]->needsFileAllocation());
|
||||||
CPPUNIT_ASSERT(!entries[8]->getDiskWriter().isNull());
|
CPPUNIT_ASSERT(!entries[8]->getDiskWriter().isNull());
|
||||||
// fileA
|
// fileA
|
||||||
CPPUNIT_ASSERT_EQUAL(prefix+std::string("/fileA"),
|
CPPUNIT_ASSERT_EQUAL(prefix+std::string("/fileA"),
|
||||||
|
|
Loading…
Reference in New Issue