2009-07-04 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Made URI reusing function work.
	* src/CreateRequestCommand.cc
	* src/FileEntry.cc
	* src/FileEntry.h
	* test/FileEntryTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-07-04 13:36:56 +00:00
parent 3a655a5d1a
commit a7c222b8ab
5 changed files with 74 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2009-07-04 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Made URI reusing function work.
* src/CreateRequestCommand.cc
* src/FileEntry.cc
* src/FileEntry.h
* test/FileEntryTest.cc
2009-07-04 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Add formerly fastest PeerStat's sessionDownloadLength to new

View File

@ -67,6 +67,10 @@ bool CreateRequestCommand::executeInternal()
_fileEntry = _requestGroup->getDownloadContext()->findFileEntryByOffset
(_segments.front()->getPositionToWrite());
}
if(_fileEntry->getRemainingUris().empty() &&
getOption()->getAsBool(PREF_REUSE_URI)) {
_fileEntry->reuseUri(_requestGroup->getNumConcurrentCommand());
}
req = _fileEntry->getRequest(_requestGroup->getURISelector(),
getOption()->get(PREF_REFERER),
// Don't use HEAD request when file

View File

@ -278,4 +278,39 @@ void FileEntry::extractURIResult
_uriResults.erase(_uriResults.begin(), i);
}
void FileEntry::reuseUri(size_t num)
{
std::deque<std::string> uris = _spentUris;
std::sort(uris.begin(), uris.end());
uris.erase(std::unique(uris.begin(), uris.end()), uris.end());
std::deque<std::string> errorUris(_uriResults.size());
std::transform(_uriResults.begin(), _uriResults.end(),
errorUris.begin(), std::mem_fun_ref(&URIResult::getURI));
std::sort(errorUris.begin(), errorUris.end());
errorUris.erase(std::unique(errorUris.begin(), errorUris.end()),
errorUris.end());
std::deque<std::string> reusableURIs;
std::set_difference(uris.begin(), uris.end(),
errorUris.begin(), errorUris.end(),
std::back_inserter(reusableURIs));
size_t ininum = reusableURIs.size();
_logger->debug("Found %u reusable URIs",
static_cast<unsigned int>(ininum));
// Reuse at least num URIs here to avoid to
// run this process repeatedly.
if(ininum > 0 && ininum < num) {
_logger->debug("fewer than num=%u",
num);
for(size_t i = 0; i < num/ininum; ++i) {
_uris.insert(_uris.end(), reusableURIs.begin(), reusableURIs.end());
}
_uris.insert(_uris.end(), reusableURIs.begin(),
reusableURIs.begin()+(num%ininum));
_logger->debug("Duplication complete: now %u URIs for reuse",
static_cast<unsigned int>(_uris.size()));
}
}
} // namespace aria2

View File

@ -225,6 +225,12 @@ public:
{
return _singleHostMultiConnection;
}
// Reuse URIs which have not emitted error so far. Thie method
// tries to reuse at least num URIs. If less than num URIs found to
// reuse, those URIs are used more than once so that num URIs total
// are available to reuse.
void reuseUri(size_t num);
};
typedef SharedHandle<FileEntry> FileEntryHandle;

View File

@ -14,6 +14,7 @@ class FileEntryTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testExtractURIResult);
CPPUNIT_TEST(testGetRequest);
CPPUNIT_TEST(testGetRequest_disableSingleHostMultiConnection);
CPPUNIT_TEST(testReuseUri);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@ -23,6 +24,7 @@ public:
void testExtractURIResult();
void testGetRequest();
void testGetRequest_disableSingleHostMultiConnection();
void testReuseUri();
};
@ -128,4 +130,23 @@ void FileEntryTest::testGetRequest_disableSingleHostMultiConnection()
CPPUNIT_ASSERT(req3rd.isNull());
}
void FileEntryTest::testReuseUri()
{
SharedHandle<InOrderURISelector> selector(new InOrderURISelector());
SharedHandle<FileEntry> fileEntry = createFileEntry();
size_t numUris = fileEntry->getRemainingUris().size();
for(size_t i = 0; i < numUris; ++i) {
fileEntry->getRequest(selector);
}
CPPUNIT_ASSERT_EQUAL((size_t)0, fileEntry->getRemainingUris().size());
fileEntry->addURIResult("http://localhost/aria2.zip",
downloadresultcode::UNKNOWN_ERROR);
fileEntry->reuseUri(3);
CPPUNIT_ASSERT_EQUAL((size_t)3, fileEntry->getRemainingUris().size());
const std::deque<std::string>& uris = fileEntry->getRemainingUris();
CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"), uris[0]);
CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.zip"), uris[1]);
CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"), uris[2]);
}
} // namespace aria2