/* */ #include "AdaptiveFileAllocationIterator.h" #include "BinaryStream.h" #include "SingleFileAllocationIterator.h" #include "RecoverableException.h" #include "LogFactory.h" #include "Logger.h" #include "a2functional.h" #ifdef HAVE_FALLOCATE # include "FallocFileAllocationIterator.h" #endif // HAVE_FALLOCATE namespace aria2 { AdaptiveFileAllocationIterator::AdaptiveFileAllocationIterator( BinaryStream* stream, int64_t offset, int64_t totalLength) : stream_(stream), offset_(offset), totalLength_(totalLength) { } AdaptiveFileAllocationIterator::~AdaptiveFileAllocationIterator() = default; void AdaptiveFileAllocationIterator::allocateChunk() { if (!allocator_) { #ifdef HAVE_FALLOCATE try { A2_LOG_DEBUG("Testing file system supports fallocate."); if (offset_ < totalLength_) { int64_t len = std::min(totalLength_ - offset_, static_cast(4_k)); stream_->allocate(offset_, len, false); offset_ += len; } A2_LOG_DEBUG("File system supports fallocate."); allocator_ = make_unique(stream_, offset_, totalLength_); } catch (RecoverableException& e) { A2_LOG_DEBUG("File system does not support fallocate."); auto salloc = make_unique(stream_, offset_, totalLength_); salloc->init(); allocator_ = std::move(salloc); } #else // !HAVE_FALLOCATE auto salloc = make_unique(stream_, offset_, totalLength_); salloc->init(); allocator_ = std::move(salloc); #endif // !HAVE_FALLOCATE allocator_->allocateChunk(); } else { allocator_->allocateChunk(); } } bool AdaptiveFileAllocationIterator::finished() { if (!allocator_) { return offset_ == totalLength_; } else { return allocator_->finished(); } } int64_t AdaptiveFileAllocationIterator::getCurrentLength() { if (!allocator_) { return offset_; } else { return allocator_->getCurrentLength(); } } int64_t AdaptiveFileAllocationIterator::getTotalLength() { return totalLength_; } } // namespace aria2