diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-11-28 14:22:28 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-11-28 14:22:28 +0000 |
| commit | 5a2f398eca68b2b0330ddcec2b222bf76875f82f (patch) | |
| tree | eb916885f04126e7e48b56fe02de6b44f0493c17 /src/MultiFileAllocationIterator.cc | |
| parent | a022a1826bb573028f264bc6edbc564c0d488bbc (diff) | |
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
Diffstat (limited to 'src/MultiFileAllocationIterator.cc')
| -rw-r--r-- | src/MultiFileAllocationIterator.cc | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/src/MultiFileAllocationIterator.cc b/src/MultiFileAllocationIterator.cc index 7d8cdfcb..04961ae6 100644 --- a/src/MultiFileAllocationIterator.cc +++ b/src/MultiFileAllocationIterator.cc @@ -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; |
