From 1944d8db58555c08b5f069a2e987fcfdd5aad997 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 30 May 2014 23:20:13 +0900 Subject: [PATCH] Save session only when there is change since the last serialization This is a slight optimization not to cause useless disk access. This only applies to saving session automatically (see --save-session-interval). aria2.saveSession and serialization at the end of the session are always performed as before. --- src/RequestGroupMan.cc | 25 +++++++++++++++++++++++-- src/RequestGroupMan.h | 15 +++++++++++++++ src/SaveSessionCommand.cc | 15 +++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index ac2eba8f..a8729ffa 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -111,6 +111,7 @@ RequestGroupMan::RequestGroupMan (PREF_MAX_OVERALL_UPLOAD_LIMIT)), keepRunning_(option->getAsBool(PREF_ENABLE_RPC)), queueCheck_(true), + requireSaveSession_(false), removedErrorResult_(0), removedLastErrorResult_(error_code::FINISHED), maxDownloadResult_(option->getAsInt(PREF_MAX_DOWNLOAD_RESULT)), @@ -120,6 +121,9 @@ RequestGroupMan::RequestGroupMan { appendReservedGroup(reservedGroups_, requestGroups.begin(), requestGroups.end()); + if(!reservedGroups_.empty()) { + requireSaveSession_ = true; + } } RequestGroupMan::~RequestGroupMan() @@ -139,6 +143,7 @@ void RequestGroupMan::addRequestGroup (const std::shared_ptr& group) { requestGroups_.push_back(group->getGID(), group); + requireSaveSession_ = true; } void RequestGroupMan::addReservedGroup @@ -146,6 +151,9 @@ void RequestGroupMan::addReservedGroup { requestQueueCheck(); appendReservedGroup(reservedGroups_, groups.begin(), groups.end()); + if(!reservedGroups_.empty()) { + requireSaveSession_ = true; + } } void RequestGroupMan::addReservedGroup @@ -153,6 +161,7 @@ void RequestGroupMan::addReservedGroup { requestQueueCheck(); reservedGroups_.push_back(group->getGID(), group); + requireSaveSession_ = true; } namespace { @@ -171,6 +180,7 @@ void RequestGroupMan::insertReservedGroup pos = std::min(reservedGroups_.size(), pos); reservedGroups_.insert(pos, RequestGroupKeyFunc(), groups.begin(), groups.end()); + requireSaveSession_ = true; } void RequestGroupMan::insertReservedGroup @@ -179,6 +189,7 @@ void RequestGroupMan::insertReservedGroup requestQueueCheck(); pos = std::min(reservedGroups_.size(), pos); reservedGroups_.insert(pos, group->getGID(), group); + requireSaveSession_ = true; } size_t RequestGroupMan::countRequestGroup() const @@ -202,13 +213,16 @@ size_t RequestGroupMan::changeReservedGroupPosition if(dest == -1) { throw DL_ABORT_EX(fmt("GID#%s not found in the waiting queue.", GroupId::toHex(gid).c_str())); - } else { - return dest; } + + requireSaveSession_ = true; + + return dest; } bool RequestGroupMan::removeReservedGroup(a2_gid_t gid) { + requireSaveSession_ = true; return reservedGroups_.remove(gid); } @@ -387,6 +401,7 @@ public: } catch(RecoverableException& ex) { A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, ex); } + if(group->isPauseRequested()) { group->setState(RequestGroup::STATE_WAITING); reservedGroups_.push_front(group->getGID(), group); @@ -417,6 +432,7 @@ void RequestGroupMan::removeStoppedGroup(DownloadEngine* e) requestGroups_.remove_if(ProcessStoppedRequestGroup(e, reservedGroups_)); size_t numRemoved = numPrev-requestGroups_.size(); if(numRemoved > 0) { + requireSaveSession_ = true; A2_LOG_DEBUG(fmt("%lu RequestGroup(s) deleted.", static_cast(numRemoved))); } @@ -466,6 +482,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e) uriListParser_.get()); if(ok) { appendReservedGroup(reservedGroups_, groups.begin(), groups.end()); + requireSaveSession_ = true; } else { uriListParser_.reset(); if(reservedGroups_.empty()) { @@ -487,6 +504,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e) groupToAdd->setRequestGroupMan(this); groupToAdd->setState(RequestGroup::STATE_ACTIVE); requestGroups_.push_back(groupToAdd->getGID(), groupToAdd); + requireSaveSession_ = true; try { auto res = createInitialCommand(groupToAdd, e); ++count; @@ -828,6 +846,7 @@ RequestGroupMan::findDownloadResult(a2_gid_t gid) const bool RequestGroupMan::removeDownloadResult(a2_gid_t gid) { + requireSaveSession_ = true; return downloadResults_.remove(gid); } @@ -836,6 +855,7 @@ void RequestGroupMan::addDownloadResult(const std::shared_ptr& d ++numStoppedTotal_; bool rv = downloadResults_.push_back(dr->gid->getNumericId(), dr); assert(rv); + requireSaveSession_ = true; while(downloadResults_.size() > maxDownloadResult_){ DownloadResultList::iterator i = downloadResults_.begin(); // Save last encountered error code so that we can report it @@ -851,6 +871,7 @@ void RequestGroupMan::addDownloadResult(const std::shared_ptr& d void RequestGroupMan::purgeDownloadResult() { + requireSaveSession_ = true; downloadResults_.clear(); } diff --git a/src/RequestGroupMan.h b/src/RequestGroupMan.h index bbee4529..7cd63059 100644 --- a/src/RequestGroupMan.h +++ b/src/RequestGroupMan.h @@ -90,6 +90,11 @@ private: bool queueCheck_; + // true if there is a change in at least one of requestGroups_, + // reservedGroups_ and downloadResults_ since the last session + // serialization, so we need to save session file next time. + bool requireSaveSession_; + // The number of error DownloadResult removed because of upper limit // of the queue int removedErrorResult_; @@ -368,6 +373,16 @@ public: { return numStoppedTotal_; } + + bool getRequireSaveSession() const + { + return requireSaveSession_; + } + + void clearRequireSaveSession() + { + requireSaveSession_ = false; + } }; } // namespace aria2 diff --git a/src/SaveSessionCommand.cc b/src/SaveSessionCommand.cc index d94815ad..7e557f27 100644 --- a/src/SaveSessionCommand.cc +++ b/src/SaveSessionCommand.cc @@ -60,12 +60,23 @@ void SaveSessionCommand::preProcess() void SaveSessionCommand::process() { + auto& rgman = getDownloadEngine()->getRequestGroupMan(); + + if(!rgman->getRequireSaveSession()) { + A2_LOG_INFO("No change in queues since last serialization or startup. " + "No serialization is necessary this time."); + return; + } + const std::string& filename = getDownloadEngine()->getOption() ->get(PREF_SAVE_SESSION); + if(!filename.empty()) { - SessionSerializer sessionSerializer(getDownloadEngine()-> - getRequestGroupMan().get()); + SessionSerializer sessionSerializer(rgman.get()); + if(sessionSerializer.save(filename)) { + rgman->clearRequireSaveSession(); + A2_LOG_NOTICE(fmt(_("Serialized session to '%s' successfully."), filename.c_str())); } else {