MultiDiskWriter: Rewrite resetDiskWriterEntries() using simpler algorithm

pull/106/head
Tatsuhiro Tsujikawa 2013-07-05 21:42:01 +09:00
parent f000fd0cab
commit 345ba415a5
1 changed files with 31 additions and 60 deletions

View File

@ -139,76 +139,47 @@ std::unique_ptr<DiskWriterEntry> createDiskWriterEntry
void MultiDiskAdaptor::resetDiskWriterEntries() void MultiDiskAdaptor::resetDiskWriterEntries()
{ {
diskWriterEntries_.clear(); diskWriterEntries_.clear();
if(getFileEntries().empty()) { if(getFileEntries().empty()) {
return; return;
} }
for(auto& fileEntry: getFileEntries()) { for(auto& fileEntry: getFileEntries()) {
diskWriterEntries_.push_back(createDiskWriterEntry(fileEntry)); diskWriterEntries_.push_back(createDiskWriterEntry(fileEntry));
} }
// 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) {
auto done = std::begin(diskWriterEntries_); // Check shared piece forward
for(auto itr = std::begin(diskWriterEntries_), int64_t lastOffset = 0;
eoi = std::end(diskWriterEntries_); itr != eoi;) { for(auto& dwent : diskWriterEntries_) {
auto& fileEntry = (*itr)->getFileEntry(); auto& fileEntry = dwent->getFileEntry();
if(!fileEntry->isRequested()) { if(fileEntry->isRequested()) {
++itr; // zero length file does not affect lastOffset.
continue;
}
int64_t pieceStartOffset =
(fileEntry->getOffset()/pieceLength_)*pieceLength_;
if(itr != std::begin(diskWriterEntries_)) {
for(auto i = itr-1;; --i) {
auto& fileEntry = (*i)->getFileEntry();
if(pieceStartOffset <= fileEntry->getOffset() ||
pieceStartOffset < fileEntry->getLastOffset()) {
A2_LOG_DEBUG(fmt("%s needs file allocation",
(*i)->getFileEntry()->getPath().c_str()));
(*i)->needsFileAllocation(true);
} else {
break;
}
if(i == done) {
break;
}
}
}
if(fileEntry->getLength() > 0) { if(fileEntry->getLength() > 0) {
int64_t lastPieceStartOffset = lastOffset = (fileEntry->getLastOffset()-1)/pieceLength_
(fileEntry->getOffset()+fileEntry->getLength()-1)/ * pieceLength_ + pieceLength_;
pieceLength_*pieceLength_; }
A2_LOG_DEBUG(fmt("Checking adjacent backward file to %s" } else if(fileEntry->getOffset() < lastOffset) {
" whose lastPieceStartOffset+pieceLength_=%" PRId64 "", // The files which shares last piece are not needed to be
fileEntry->getPath().c_str(), // allocated. They just requre DiskWriter
static_cast<int64_t> A2_LOG_DEBUG(fmt("%s needs DiskWriter",
(lastPieceStartOffset+pieceLength_))); fileEntry->getPath().c_str()));
++itr; dwent->needsDiskWriter(true);
// adjacent backward files are not needed to be allocated. They
// just requre DiskWriter
for(; itr != eoi &&
(!(*itr)->getFileEntry()->isRequested() ||
(*itr)->getFileEntry()->getLength() == 0); ++itr) {
A2_LOG_DEBUG
(fmt("file=%s, offset=%" PRId64 "",
(*itr)->getFileEntry()->getPath().c_str(),
(*itr)->getFileEntry()->getOffset()));
if((*itr)->getFileEntry()->getOffset() <
lastPieceStartOffset+pieceLength_) {
A2_LOG_DEBUG
(fmt("%s needs diskwriter",
(*itr)->getFileEntry()->getPath().c_str()));
(*itr)->needsDiskWriter(true);
} else {
break;
} }
} }
done = itr-1; // Check shared piece backword
} else { lastOffset = std::numeric_limits<int64_t>::max();
done = itr; for(auto i = diskWriterEntries_.rbegin(), eoi = diskWriterEntries_.rend();
++itr; i != eoi; ++i) {
auto& fileEntry = (*i)->getFileEntry();
if(fileEntry->isRequested()) {
lastOffset = fileEntry->getOffset()/pieceLength_*pieceLength_;
} else if(lastOffset <= fileEntry->getOffset() || // length == 0 case
lastOffset < fileEntry->getLastOffset()) {
// We needs last part of the file, so file allocation is
// required, especially for file system which does not support
// sparse files.
A2_LOG_DEBUG(fmt("%s needs file allocation",
fileEntry->getPath().c_str()));
(*i)->needsFileAllocation(true);
} }
} }
} }