summaryrefslogtreecommitdiff
path: root/src/SegmentMan.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/SegmentMan.cc')
-rw-r--r--src/SegmentMan.cc289
1 files changed, 156 insertions, 133 deletions
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index a5b4fc30..c3167285 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -59,18 +59,18 @@
namespace aria2 {
SegmentEntry::SegmentEntry(cuid_t cuid, const std::shared_ptr<Segment>& segment)
- : cuid(cuid), segment(segment)
-{}
+ : cuid(cuid), segment(segment)
+{
+}
SegmentEntry::~SegmentEntry() {}
-SegmentMan::SegmentMan
-(const std::shared_ptr<DownloadContext>& downloadContext,
- const std::shared_ptr<PieceStorage>& pieceStorage)
- : downloadContext_(downloadContext),
- pieceStorage_(pieceStorage),
- ignoreBitfield_(downloadContext->getPieceLength(),
- downloadContext->getTotalLength())
+SegmentMan::SegmentMan(const std::shared_ptr<DownloadContext>& downloadContext,
+ const std::shared_ptr<PieceStorage>& pieceStorage)
+ : downloadContext_(downloadContext),
+ pieceStorage_(pieceStorage),
+ ignoreBitfield_(downloadContext->getPieceLength(),
+ downloadContext->getTotalLength())
{
ignoreBitfield_.enableFilter();
}
@@ -79,9 +79,10 @@ SegmentMan::~SegmentMan() {}
bool SegmentMan::downloadFinished() const
{
- if(!pieceStorage_) {
+ if (!pieceStorage_) {
return false;
- } else {
+ }
+ else {
return pieceStorage_->downloadFinished();
}
}
@@ -94,20 +95,22 @@ void SegmentMan::init()
int64_t SegmentMan::getTotalLength() const
{
- if(!pieceStorage_) {
+ if (!pieceStorage_) {
return 0;
- } else {
+ }
+ else {
return pieceStorage_->getTotalLength();
}
}
-void SegmentMan::setPieceStorage(const std::shared_ptr<PieceStorage>& pieceStorage)
+void SegmentMan::setPieceStorage(
+ const std::shared_ptr<PieceStorage>& pieceStorage)
{
pieceStorage_ = pieceStorage;
}
-void SegmentMan::setDownloadContext
-(const std::shared_ptr<DownloadContext>& downloadContext)
+void SegmentMan::setDownloadContext(
+ const std::shared_ptr<DownloadContext>& downloadContext)
{
downloadContext_ = downloadContext;
}
@@ -117,157 +120,161 @@ void flushWrDiskCache(WrDiskCache* wrDiskCache,
const std::shared_ptr<Piece>& piece)
{
piece->flushWrCache(wrDiskCache);
- if(piece->getWrDiskCacheEntry()->getError() !=
- WrDiskCacheEntry::CACHE_ERR_SUCCESS) {
+ if (piece->getWrDiskCacheEntry()->getError() !=
+ WrDiskCacheEntry::CACHE_ERR_SUCCESS) {
piece->clearAllBlock(wrDiskCache);
- throw DOWNLOAD_FAILURE_EXCEPTION2
- (fmt("Write disk cache flush failure index=%lu",
- static_cast<unsigned long>(piece->getIndex())),
- piece->getWrDiskCacheEntry()->getErrorCode());
+ throw DOWNLOAD_FAILURE_EXCEPTION2(
+ fmt("Write disk cache flush failure index=%lu",
+ static_cast<unsigned long>(piece->getIndex())),
+ piece->getWrDiskCacheEntry()->getErrorCode());
}
}
} // namespace
-std::shared_ptr<Segment> SegmentMan::checkoutSegment
-(cuid_t cuid, const std::shared_ptr<Piece>& piece)
+std::shared_ptr<Segment>
+SegmentMan::checkoutSegment(cuid_t cuid, const std::shared_ptr<Piece>& piece)
{
- if(!piece) {
+ if (!piece) {
return nullptr;
}
A2_LOG_DEBUG(fmt("Attach segment#%lu to CUID#%" PRId64 ".",
- static_cast<unsigned long>(piece->getIndex()),
- cuid));
+ static_cast<unsigned long>(piece->getIndex()), cuid));
- if(piece->getWrDiskCacheEntry()) {
+ if (piece->getWrDiskCacheEntry()) {
// Flush cached data here, because the cached data may be overlapped
// if BT peers are involved.
- A2_LOG_DEBUG(fmt("Flushing cached data, size=%lu",
- static_cast<unsigned long>(piece->getWrDiskCacheEntry()->
- getSize())));
+ A2_LOG_DEBUG(fmt(
+ "Flushing cached data, size=%lu",
+ static_cast<unsigned long>(piece->getWrDiskCacheEntry()->getSize())));
flushWrDiskCache(pieceStorage_->getWrDiskCache(), piece);
}
piece->setUsedBySegment(true);
std::shared_ptr<Segment> segment;
- if(piece->getLength() == 0) {
+ if (piece->getLength() == 0) {
segment = std::make_shared<GrowSegment>(piece);
- } else {
- segment = std::make_shared<PiecedSegment>
- (downloadContext_->getPieceLength(), piece);
+ }
+ else {
+ segment = std::make_shared<PiecedSegment>(
+ downloadContext_->getPieceLength(), piece);
}
auto entry = std::make_shared<SegmentEntry>(cuid, segment);
usedSegmentEntries_.push_back(entry);
A2_LOG_DEBUG(fmt("index=%lu, length=%" PRId64 ", segmentLength=%" PRId64 ","
" writtenLength=%" PRId64,
static_cast<unsigned long>(segment->getIndex()),
- segment->getLength(),
- segment->getSegmentLength(),
+ segment->getLength(), segment->getSegmentLength(),
segment->getWrittenLength()));
- if(piece->getLength() > 0) {
+ if (piece->getLength() > 0) {
auto positr = segmentWrittenLengthMemo_.find(segment->getIndex());
- if(positr != segmentWrittenLengthMemo_.end()) {
+ if (positr != segmentWrittenLengthMemo_.end()) {
const auto writtenLength = (*positr).second;
- A2_LOG_DEBUG(fmt("writtenLength(in memo)=%" PRId64 ", writtenLength=%" PRId64,
+ A2_LOG_DEBUG(fmt("writtenLength(in memo)=%" PRId64
+ ", writtenLength=%" PRId64,
writtenLength, segment->getWrittenLength()));
// If the difference between cached writtenLength and segment's
// writtenLength is less than one block, we assume that these
// missing bytes are already downloaded.
- if(segment->getWrittenLength() < writtenLength &&
- writtenLength-segment->getWrittenLength() < piece->getBlockLength()) {
- segment->updateWrittenLength(writtenLength-segment->getWrittenLength());
+ if (segment->getWrittenLength() < writtenLength &&
+ writtenLength - segment->getWrittenLength() <
+ piece->getBlockLength()) {
+ segment->updateWrittenLength(writtenLength -
+ segment->getWrittenLength());
}
}
}
return segment;
}
-void SegmentMan::getInFlightSegment
-(std::vector<std::shared_ptr<Segment> >& segments, cuid_t cuid)
+void SegmentMan::getInFlightSegment(
+ std::vector<std::shared_ptr<Segment>>& segments, cuid_t cuid)
{
- for(SegmentEntries::const_iterator itr = usedSegmentEntries_.begin(),
- eoi = usedSegmentEntries_.end(); itr != eoi; ++itr) {
+ for (SegmentEntries::const_iterator itr = usedSegmentEntries_.begin(),
+ eoi = usedSegmentEntries_.end();
+ itr != eoi; ++itr) {
const std::shared_ptr<SegmentEntry>& segmentEntry = *itr;
- if(segmentEntry->cuid == cuid) {
+ if (segmentEntry->cuid == cuid) {
segments.push_back(segmentEntry->segment);
}
}
}
-std::shared_ptr<Segment> SegmentMan::getSegment(cuid_t cuid, size_t minSplitSize)
+std::shared_ptr<Segment> SegmentMan::getSegment(cuid_t cuid,
+ size_t minSplitSize)
{
- std::shared_ptr<Piece> piece =
- pieceStorage_->getMissingPiece
- (minSplitSize,
- ignoreBitfield_.getFilterBitfield(), ignoreBitfield_.getBitfieldLength(),
- cuid);
+ std::shared_ptr<Piece> piece = pieceStorage_->getMissingPiece(
+ minSplitSize, ignoreBitfield_.getFilterBitfield(),
+ ignoreBitfield_.getBitfieldLength(), cuid);
return checkoutSegment(cuid, piece);
}
-void SegmentMan::getSegment
-(std::vector<std::shared_ptr<Segment> >& segments,
- cuid_t cuid,
- size_t minSplitSize,
- const std::shared_ptr<FileEntry>& fileEntry,
- size_t maxSegments)
+void SegmentMan::getSegment(std::vector<std::shared_ptr<Segment>>& segments,
+ cuid_t cuid, size_t minSplitSize,
+ const std::shared_ptr<FileEntry>& fileEntry,
+ size_t maxSegments)
{
BitfieldMan filter(ignoreBitfield_);
filter.enableFilter();
filter.addNotFilter(fileEntry->getOffset(), fileEntry->getLength());
- std::vector<std::shared_ptr<Segment> > pending;
- while(segments.size() < maxSegments) {
- std::shared_ptr<Segment> segment =
- checkoutSegment(cuid,
- pieceStorage_->getMissingPiece
- (minSplitSize,
- filter.getFilterBitfield(), filter.getBitfieldLength(),
- cuid));
- if(!segment) {
+ std::vector<std::shared_ptr<Segment>> pending;
+ while (segments.size() < maxSegments) {
+ std::shared_ptr<Segment> segment = checkoutSegment(
+ cuid,
+ pieceStorage_->getMissingPiece(minSplitSize, filter.getFilterBitfield(),
+ filter.getBitfieldLength(), cuid));
+ if (!segment) {
break;
}
- if(segment->getPositionToWrite() < fileEntry->getOffset() ||
- fileEntry->getLastOffset() <= segment->getPositionToWrite()) {
+ if (segment->getPositionToWrite() < fileEntry->getOffset() ||
+ fileEntry->getLastOffset() <= segment->getPositionToWrite()) {
pending.push_back(segment);
- } else {
+ }
+ else {
segments.push_back(segment);
}
}
- for(std::vector<std::shared_ptr<Segment> >::const_iterator i = pending.begin(),
- eoi = pending.end(); i != eoi; ++i) {
+ for (std::vector<std::shared_ptr<Segment>>::const_iterator
+ i = pending.begin(),
+ eoi = pending.end();
+ i != eoi; ++i) {
cancelSegment(cuid, *i);
}
}
-std::shared_ptr<Segment> SegmentMan::getSegmentWithIndex
-(cuid_t cuid, size_t index) {
- if(index > 0 && downloadContext_->getNumPieces() <= index) {
+std::shared_ptr<Segment> SegmentMan::getSegmentWithIndex(cuid_t cuid,
+ size_t index)
+{
+ if (index > 0 && downloadContext_->getNumPieces() <= index) {
return nullptr;
}
return checkoutSegment(cuid, pieceStorage_->getMissingPiece(index, cuid));
}
-std::shared_ptr<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
-(cuid_t cuid, size_t index)
+std::shared_ptr<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle(cuid_t cuid,
+ size_t index)
{
- if(index > 0 && downloadContext_->getNumPieces() <= index) {
+ if (index > 0 && downloadContext_->getNumPieces() <= index) {
return nullptr;
}
- for(SegmentEntries::const_iterator itr = usedSegmentEntries_.begin(),
- eoi = usedSegmentEntries_.end(); itr != eoi; ++itr) {
+ for (SegmentEntries::const_iterator itr = usedSegmentEntries_.begin(),
+ eoi = usedSegmentEntries_.end();
+ itr != eoi; ++itr) {
const std::shared_ptr<SegmentEntry>& segmentEntry = *itr;
- if(segmentEntry->segment->getIndex() == index) {
- if(segmentEntry->segment->getWrittenLength() > 0) {
+ if (segmentEntry->segment->getIndex() == index) {
+ if (segmentEntry->segment->getWrittenLength() > 0) {
return nullptr;
}
- if(segmentEntry->cuid == cuid) {
+ if (segmentEntry->cuid == cuid) {
return segmentEntry->segment;
}
cuid_t owner = segmentEntry->cuid;
std::shared_ptr<PeerStat> ps = getPeerStat(owner);
- if(!ps || ps->getStatus() == NetStat::IDLE) {
+ if (!ps || ps->getStatus() == NetStat::IDLE) {
cancelSegment(owner);
return getSegmentWithIndex(cuid, index);
- } else {
+ }
+ else {
return nullptr;
}
}
@@ -275,21 +282,20 @@ std::shared_ptr<Segment> SegmentMan::getCleanSegmentIfOwnerIsIdle
return nullptr;
}
-void SegmentMan::cancelSegmentInternal
-(cuid_t cuid,
- const std::shared_ptr<Segment>& segment)
+void SegmentMan::cancelSegmentInternal(cuid_t cuid,
+ const std::shared_ptr<Segment>& segment)
{
A2_LOG_DEBUG(fmt("Canceling segment#%lu",
static_cast<unsigned long>(segment->getIndex())));
const std::shared_ptr<Piece>& piece = segment->getPiece();
// TODO In PieceStorage::cancelPiece(), WrDiskCacheEntry may be
// released. Flush first.
- if(piece->getWrDiskCacheEntry()) {
+ if (piece->getWrDiskCacheEntry()) {
// Flush cached data here, because the cached data may be overlapped
// if BT peers are involved.
- A2_LOG_DEBUG(fmt("Flushing cached data, size=%lu",
- static_cast<unsigned long>(piece->getWrDiskCacheEntry()
- ->getSize())));
+ A2_LOG_DEBUG(fmt(
+ "Flushing cached data, size=%lu",
+ static_cast<unsigned long>(piece->getWrDiskCacheEntry()->getSize())));
flushWrDiskCache(pieceStorage_->getWrDiskCache(), piece);
// TODO Exception may cause some segments (pieces) are not
// canceled.
@@ -302,29 +308,32 @@ void SegmentMan::cancelSegmentInternal
segment->getWrittenLength()));
}
-void SegmentMan::cancelSegment(cuid_t cuid) {
- for(auto itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end();
- itr != eoi;) {
- if((*itr)->cuid == cuid) {
+void SegmentMan::cancelSegment(cuid_t cuid)
+{
+ for (auto itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end();
+ itr != eoi;) {
+ if ((*itr)->cuid == cuid) {
cancelSegmentInternal(cuid, (*itr)->segment);
itr = usedSegmentEntries_.erase(itr);
eoi = usedSegmentEntries_.end();
- } else {
+ }
+ else {
++itr;
}
}
}
-void SegmentMan::cancelSegment
-(cuid_t cuid, const std::shared_ptr<Segment>& segment)
+void SegmentMan::cancelSegment(cuid_t cuid,
+ const std::shared_ptr<Segment>& segment)
{
- for(auto itr = usedSegmentEntries_.begin(),
- eoi = usedSegmentEntries_.end(); itr != eoi;) {
- if((*itr)->cuid == cuid && *(*itr)->segment == *segment) {
+ for (auto itr = usedSegmentEntries_.begin(), eoi = usedSegmentEntries_.end();
+ itr != eoi;) {
+ if ((*itr)->cuid == cuid && *(*itr)->segment == *segment) {
cancelSegmentInternal(cuid, (*itr)->segment);
itr = usedSegmentEntries_.erase(itr);
break;
- } else {
+ }
+ else {
++itr;
}
}
@@ -332,7 +341,7 @@ void SegmentMan::cancelSegment
void SegmentMan::cancelAllSegments()
{
- for(auto& e: usedSegmentEntries_) {
+ for (auto& e : usedSegmentEntries_) {
cancelSegmentInternal(e->cuid, e->segment);
}
usedSegmentEntries_.clear();
@@ -347,8 +356,12 @@ namespace {
class FindSegmentEntry {
private:
std::shared_ptr<Segment> segment_;
+
public:
- FindSegmentEntry(std::shared_ptr<Segment> segment):segment_(std::move(segment)) {}
+ FindSegmentEntry(std::shared_ptr<Segment> segment)
+ : segment_(std::move(segment))
+ {
+ }
bool operator()(const std::shared_ptr<SegmentEntry>& segmentEntry) const
{
@@ -357,29 +370,33 @@ public:
};
} // namespace
-bool SegmentMan::completeSegment
-(cuid_t cuid, const std::shared_ptr<Segment>& segment) {
+bool SegmentMan::completeSegment(cuid_t cuid,
+ const std::shared_ptr<Segment>& segment)
+{
pieceStorage_->completePiece(segment->getPiece());
pieceStorage_->advertisePiece(cuid, segment->getPiece()->getIndex());
auto itr = std::find_if(usedSegmentEntries_.begin(),
- usedSegmentEntries_.end(),
- FindSegmentEntry(segment));
- if(itr == usedSegmentEntries_.end()) {
+ usedSegmentEntries_.end(), FindSegmentEntry(segment));
+ if (itr == usedSegmentEntries_.end()) {
return false;
- } else {
+ }
+ else {
usedSegmentEntries_.erase(itr);
return true;
}
}
-bool SegmentMan::hasSegment(size_t index) const {
+bool SegmentMan::hasSegment(size_t index) const
+{
return pieceStorage_->hasPiece(index);
}
-int64_t SegmentMan::getDownloadLength() const {
- if(!pieceStorage_) {
+int64_t SegmentMan::getDownloadLength() const
+{
+ if (!pieceStorage_) {
return 0;
- } else {
+ }
+ else {
return pieceStorage_->getCompletedLength();
}
}
@@ -391,8 +408,8 @@ void SegmentMan::registerPeerStat(const std::shared_ptr<PeerStat>& peerStat)
std::shared_ptr<PeerStat> SegmentMan::getPeerStat(cuid_t cuid) const
{
- for(auto& e: peerStats_) {
- if(e->getCuid() == cuid) {
+ for (auto& e : peerStats_) {
+ if (e->getCuid() == cuid) {
return e;
}
}
@@ -403,29 +420,35 @@ namespace {
class PeerStatHostProtoEqual {
private:
const std::shared_ptr<PeerStat>& peerStat_;
+
public:
- PeerStatHostProtoEqual(const std::shared_ptr<PeerStat>& peerStat):
- peerStat_(peerStat) {}
+ PeerStatHostProtoEqual(const std::shared_ptr<PeerStat>& peerStat)
+ : peerStat_(peerStat)
+ {
+ }
bool operator()(const std::shared_ptr<PeerStat>& p) const
{
return peerStat_->getHostname() == p->getHostname() &&
- peerStat_->getProtocol() == p->getProtocol();
+ peerStat_->getProtocol() == p->getProtocol();
}
};
} // namespace
-void SegmentMan::updateFastestPeerStat(const std::shared_ptr<PeerStat>& peerStat)
+void SegmentMan::updateFastestPeerStat(
+ const std::shared_ptr<PeerStat>& peerStat)
{
auto i = std::find_if(fastestPeerStats_.begin(), fastestPeerStats_.end(),
PeerStatHostProtoEqual(peerStat));
- if(i == fastestPeerStats_.end()) {
+ if (i == fastestPeerStats_.end()) {
fastestPeerStats_.push_back(peerStat);
- } else if((*i)->getAvgDownloadSpeed() < peerStat->getAvgDownloadSpeed()) {
+ }
+ else if ((*i)->getAvgDownloadSpeed() < peerStat->getAvgDownloadSpeed()) {
// *i's SessionDownloadLength must be added to peerStat
peerStat->addSessionDownloadLength((*i)->getSessionDownloadLength());
*i = peerStat;
- } else {
+ }
+ else {
// peerStat's SessionDownloadLength must be added to *i
(*i)->addSessionDownloadLength(peerStat->getSessionDownloadLength());
}
@@ -434,25 +457,25 @@ void SegmentMan::updateFastestPeerStat(const std::shared_ptr<PeerStat>& peerStat
size_t SegmentMan::countFreePieceFrom(size_t index) const
{
size_t numPieces = downloadContext_->getNumPieces();
- for(size_t i = index; i < numPieces; ++i) {
- if(pieceStorage_->hasPiece(i) || pieceStorage_->isPieceUsed(i)) {
- return i-index;
+ for (size_t i = index; i < numPieces; ++i) {
+ if (pieceStorage_->hasPiece(i) || pieceStorage_->isPieceUsed(i)) {
+ return i - index;
}
}
- return downloadContext_->getNumPieces()-index;
+ return downloadContext_->getNumPieces() - index;
}
void SegmentMan::ignoreSegmentFor(const std::shared_ptr<FileEntry>& fileEntry)
{
A2_LOG_DEBUG(fmt("ignoring segment for path=%s, offset=%" PRId64
", length=%" PRId64 "",
- fileEntry->getPath().c_str(),
- fileEntry->getOffset(),
+ fileEntry->getPath().c_str(), fileEntry->getOffset(),
fileEntry->getLength()));
ignoreBitfield_.addFilter(fileEntry->getOffset(), fileEntry->getLength());
}
-void SegmentMan::recognizeSegmentFor(const std::shared_ptr<FileEntry>& fileEntry)
+void SegmentMan::recognizeSegmentFor(
+ const std::shared_ptr<FileEntry>& fileEntry)
{
ignoreBitfield_.removeFilter(fileEntry->getOffset(), fileEntry->getLength());
}