/* */ #include "MultiFileAllocationIterator.h" #include "MultiDiskAdaptor.h" #include "FileEntry.h" #include "SingleFileAllocationIterator.h" MultiFileAllocationIterator::MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor): _diskAdaptor(diskAdaptor), _entries(makeDiskWriterEntries(diskAdaptor->diskWriterEntries, diskAdaptor->getPieceLength())), _fileAllocationIterator(0), _offset(0) {} MultiFileAllocationIterator::~MultiFileAllocationIterator() {} void MultiFileAllocationIterator::allocateChunk() { 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()) { entry->getDiskWriter()->enableDirectIO(); _fileAllocationIterator = new SingleFileAllocationIterator(entry->getDiskWriter().get(), entry->size(), fileEntry->getLength()); _fileAllocationIterator->init(); } } if(finished()) { return; } _fileAllocationIterator->allocateChunk(); } bool MultiFileAllocationIterator::finished() { 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(_fileAllocationIterator.isNull()) { return 0; } else { return _fileAllocationIterator->getTotalLength(); } } const DiskWriterEntries& MultiFileAllocationIterator::getDiskWriterEntries() const { return _entries; } DiskWriterEntries MultiFileAllocationIterator::makeDiskWriterEntries(const DiskWriterEntries& srcEntries, int32_t pieceLength) const { if(pieceLength == 0) { DiskWriterEntries entries; for(DiskWriterEntries::const_iterator itr = srcEntries.begin(); itr != srcEntries.end(); ++itr) { if((*itr)->getFileEntry()->isRequested()) { entries.push_back(*itr); } } return entries; } 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 = (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; } } entries.push_back(*itr); done = itr; } return entries; }