mirror of https://github.com/aria2/aria2
MultiDiskWriter: Rewrite resetDiskWriterEntries() using simpler algorithm
parent
f000fd0cab
commit
345ba415a5
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue