mirror of
https://github.com/aria2/aria2.git
synced 2026-04-11 23:39:05 +00:00
2007-11-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added direct I/O support. The current implementation uses O_DIRECT,
which is not posix standard and is tested on linux 2.6.21.
Currently only file allocation uses direct I/O.
* src/SingleFileAllocationIterator.{h, cc}
* test/SingleFileAllocationIteratorTest.cc
* src/MultiFileAllocationIterator.{h, cc}
* test/MultiFileAllocationIteratorTest.cc
* src/BinaryStream.h
* src/DiskWriter.h
* src/AbstractDiskWriter.{h, cc}
* src/ByteArrayDiskWriter.h
* src/DiskAdaptor.h
* src/AbstractSingleDiskAdaptor.{h, cc}
* src/MultiDiskAdaptor.{h, cc}
* src/FileAllocationEntry.cc
* src/Util.{h, cc}
* src/OptionHandlerFactory.cc
* src/prefs.h
* src/version_usage.cc
* src/option_processing.cc
Moved FileAllocationMan::markCurrentFileAllocationEntryDone() to
handleException.
* src/MultiFileAllocationIterator.cc
Added EINTR handling
* src/SocketCore.cc
This commit is contained in:
@@ -35,96 +35,92 @@
|
||||
#include "MultiFileAllocationIterator.h"
|
||||
#include "MultiDiskAdaptor.h"
|
||||
#include "FileEntry.h"
|
||||
|
||||
#define BUFSIZE 16*1024
|
||||
#include "SingleFileAllocationIterator.h"
|
||||
|
||||
MultiFileAllocationIterator::MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor):
|
||||
_diskAdaptor(diskAdaptor),
|
||||
_entries(makeFileEntries(diskAdaptor->getFileEntries(), diskAdaptor->getPieceLength())),
|
||||
_currentEntry(0),
|
||||
_entries(makeDiskWriterEntries(diskAdaptor->diskWriterEntries,
|
||||
diskAdaptor->getPieceLength())),
|
||||
_fileAllocationIterator(0),
|
||||
_offset(0)
|
||||
{}
|
||||
|
||||
MultiFileAllocationIterator::~MultiFileAllocationIterator() {}
|
||||
|
||||
void MultiFileAllocationIterator::prepareNextEntry()
|
||||
{
|
||||
_currentEntry = 0;
|
||||
_offset = 0;
|
||||
if(!_entries.empty()) {
|
||||
FileEntryHandle entry = _entries.front();
|
||||
_entries.pop_front();
|
||||
|
||||
_currentEntry = entry;
|
||||
_offset = File(_diskAdaptor->getStoreDir()+"/"+
|
||||
_diskAdaptor->getTopDir()+"/"+
|
||||
_currentEntry->getPath()).size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MultiFileAllocationIterator::allocateChunk()
|
||||
{
|
||||
while(_currentEntry.isNull() || _currentEntry->getLength() <= _offset) {
|
||||
prepareNextEntry();
|
||||
if(_currentEntry.isNull()) {
|
||||
while(_fileAllocationIterator.isNull() || _fileAllocationIterator->finished()) {
|
||||
if(_entries.empty()) {
|
||||
break;
|
||||
}
|
||||
DiskWriterEntryHandle entry = _entries.front();
|
||||
_entries.pop_front();
|
||||
FileEntryHandle fileEntry = entry->getFileEntry();
|
||||
if(entry->size() < fileEntry->getLength()) {
|
||||
_fileAllocationIterator =
|
||||
new SingleFileAllocationIterator(entry->getDiskWriter().get(),
|
||||
entry->size(),
|
||||
fileEntry->getLength());
|
||||
_fileAllocationIterator->init();
|
||||
}
|
||||
}
|
||||
if(finished()) {
|
||||
return;
|
||||
}
|
||||
int32_t bufSize = BUFSIZE;
|
||||
unsigned char buf[BUFSIZE];
|
||||
memset(buf, 0, bufSize);
|
||||
|
||||
int32_t wsize = _offset+bufSize > _currentEntry->getLength() ?
|
||||
_currentEntry->getLength()-_offset:bufSize;
|
||||
_diskAdaptor->writeData(buf, wsize, _offset+_currentEntry->getOffset());
|
||||
_offset += wsize;
|
||||
_fileAllocationIterator->allocateChunk();
|
||||
}
|
||||
|
||||
bool MultiFileAllocationIterator::finished()
|
||||
{
|
||||
return _entries.empty() && _currentEntry.isNull();
|
||||
return _entries.empty() && (_fileAllocationIterator.isNull() || _fileAllocationIterator->finished());
|
||||
}
|
||||
|
||||
int64_t MultiFileAllocationIterator::getCurrentLength()
|
||||
{
|
||||
if(_fileAllocationIterator.isNull()) {
|
||||
return 0;
|
||||
} else {
|
||||
return _fileAllocationIterator->getCurrentLength();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t MultiFileAllocationIterator::getTotalLength()
|
||||
{
|
||||
if(_currentEntry.isNull()) {
|
||||
if(_fileAllocationIterator.isNull()) {
|
||||
return 0;
|
||||
} else {
|
||||
return _currentEntry->getLength();
|
||||
return _fileAllocationIterator->getTotalLength();
|
||||
}
|
||||
}
|
||||
|
||||
const FileEntries& MultiFileAllocationIterator::getFileEntries() const
|
||||
const DiskWriterEntries& MultiFileAllocationIterator::getDiskWriterEntries() const
|
||||
{
|
||||
return _entries;
|
||||
}
|
||||
|
||||
FileEntries MultiFileAllocationIterator::makeFileEntries(const FileEntries& srcEntries, int32_t pieceLength) const
|
||||
DiskWriterEntries MultiFileAllocationIterator::makeDiskWriterEntries(const DiskWriterEntries& srcEntries, int32_t pieceLength) const
|
||||
{
|
||||
if(pieceLength == 0) {
|
||||
FileEntries entries;
|
||||
for(FileEntries::const_iterator itr = srcEntries.begin(); itr != srcEntries.end(); ++itr) {
|
||||
if((*itr)->isRequested()) {
|
||||
DiskWriterEntries entries;
|
||||
for(DiskWriterEntries::const_iterator itr = srcEntries.begin(); itr != srcEntries.end(); ++itr) {
|
||||
if((*itr)->getFileEntry()->isRequested()) {
|
||||
entries.push_back(*itr);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
FileEntries temp(srcEntries);
|
||||
temp.push_front(new FileEntry());
|
||||
FileEntries entries;
|
||||
FileEntries::const_iterator done = temp.begin();
|
||||
for(FileEntries::const_iterator itr = temp.begin()+1; itr != temp.end(); ++itr) {
|
||||
if(!(*itr)->isRequested()) {
|
||||
DiskWriterEntries temp(srcEntries);
|
||||
temp.push_front(new DiskWriterEntry(new FileEntry()));
|
||||
DiskWriterEntries entries;
|
||||
DiskWriterEntries::const_iterator done = temp.begin();
|
||||
for(DiskWriterEntries::const_iterator itr = temp.begin()+1; itr != temp.end(); ++itr) {
|
||||
FileEntryHandle fileEntry = (*itr)->getFileEntry();
|
||||
if(!fileEntry->isRequested()) {
|
||||
continue;
|
||||
}
|
||||
int64_t pieceStartOffset = ((*itr)->getOffset()/pieceLength)*pieceLength;
|
||||
for(FileEntries::const_iterator i = itr-1; i != done; --i) {
|
||||
if(pieceStartOffset < (*i)->getOffset()+(*i)->getLength()) {
|
||||
int64_t pieceStartOffset = (fileEntry->getOffset()/pieceLength)*pieceLength;
|
||||
for(DiskWriterEntries::const_iterator i = itr-1; i != done; --i) {
|
||||
if(pieceStartOffset < (*i)->getFileEntry()->getOffset()+(*i)->getFileEntry()->getLength()) {
|
||||
entries.push_back(*i);
|
||||
} else {
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user