[new downloader] Downloading progress for groups. Calling ReportProgress for all country tree nodes.

This commit is contained in:
Vladimir Byko-Ianko 2016-02-17 10:10:50 +03:00 committed by Sergey Yershov
parent f78327d8a3
commit 8365fef2ef
3 changed files with 68 additions and 10 deletions

View file

@ -2,6 +2,7 @@
#include "std/set.hpp"
#include "std/string.hpp"
#include "std/unordered_set.hpp"
#include "std/vector.hpp"
namespace storage
@ -9,6 +10,7 @@ namespace storage
using TCountryId = string;
using TCountriesSet = set<TCountryId>;
using TCountriesVec = vector<TCountryId>;
using TCountriesUnorderedSet = unordered_set<TCountryId>;
extern const storage::TCountryId kInvalidCountryId;

View file

@ -434,6 +434,7 @@ void Storage::DownloadCountry(TCountryId const & countryId, MapOptions opt)
}
m_failedCountries.erase(countryId);
m_justDownloaded.clear();
m_queue.push_back(QueuedCountry(countryId, opt));
if (m_queue.size() == 1)
DownloadNextCountryFromQueue();
@ -524,6 +525,7 @@ void Storage::DownloadNextCountryFromQueue()
OnMapDownloadFinished(countryId, false /* success */, queuedCountry.GetInitOptions());
NotifyStatusChanged(countryId);
m_queue.pop_front();
m_justDownloaded.insert(countryId);
DownloadNextCountryFromQueue();
return;
}
@ -650,6 +652,7 @@ void Storage::OnMapFileDownloadFinished(bool success,
OnMapDownloadFinished(countryId, success, queuedCountry.GetInitOptions());
m_queue.pop_front();
m_justDownloaded.insert(countryId);
SaveDownloadQueue();
NotifyStatusChanged(countryId);
@ -665,6 +668,50 @@ void Storage::ReportProgress(TCountryId const & countryId, pair<int64_t, int64_t
o.m_progressFn(countryId, p);
}
void Storage::ReportProgressForHierarchy(TCountryId const & countryId,
pair<int64_t, int64_t> const & leafProgress)
{
// Reporting progress for a leaf in country tree.
ReportProgress(countryId, leafProgress);
// Reporting progress for the parents of the leaf with |countryId|.
TCountriesUnorderedSet hashQueue;
hashQueue.reserve(m_queue.size());
for (auto const & queuedCountry : m_queue)
hashQueue.insert(queuedCountry.GetCountryId());
// This lambda will be called for every parent of countryId (except for the root)
// to calculate and report parent's progress.
auto forEachParentExceptForTheRoot = [this, &leafProgress, &hashQueue, &countryId]
(TCountryId const & parentId, TCountriesVec & descendants)
{
pair<int64_t, int64_t> localAndRemoteBytes = make_pair(0, 0);
for (auto const & d : descendants)
{
if (d == countryId)
continue;
if (hashQueue.count(d) != 0)
{
CountryFile const & remoteCountryFile = GetCountryFile(d);
localAndRemoteBytes.second += remoteCountryFile.GetRemoteSize(MapOptions::Map);
continue;
}
if (m_justDownloaded.count(d) != 0)
{
CountryFile const & localCountryFile = GetCountryFile(d);
localAndRemoteBytes.second += localCountryFile.GetRemoteSize(MapOptions::Map);
}
}
localAndRemoteBytes.first += leafProgress.first;
localAndRemoteBytes.second += leafProgress.second;
ReportProgress(parentId, localAndRemoteBytes);
};
ForEachParentExceptForTheRoot(countryId, forEachParentExceptForTheRoot);
}
void Storage::OnServerListDownloaded(vector<string> const & urls)
{
ASSERT_THREAD_CHECKER(m_threadChecker, ());
@ -698,16 +745,10 @@ void Storage::OnMapFileDownloadProgress(MapFilesDownloader::TProgress const & pr
if (m_queue.empty())
return;
if (!m_observers.empty())
{
QueuedCountry & queuedCountry = m_queue.front();
CountryFile const & countryFile = GetCountryFile(queuedCountry.GetCountryId());
MapFilesDownloader::TProgress p = progress;
p.first += GetRemoteSize(countryFile, queuedCountry.GetDownloadedFiles(), GetCurrentDataVersion());
p.second = GetRemoteSize(countryFile, queuedCountry.GetInitOptions(), GetCurrentDataVersion());
if (m_observers.empty())
return;
ReportProgress(m_queue.front().GetCountryId(), p);
}
ReportProgressForHierarchy(m_queue.front().GetCountryId(), progress);
}
bool Storage::RegisterDownloadedFiles(TCountryId const & countryId, MapOptions files)
@ -1009,7 +1050,10 @@ bool Storage::DeleteCountryFilesFromDownloader(TCountryId const & countryId, Map
// Remove country from the queue if there's nothing to download.
if (queuedCountry->GetInitOptions() == MapOptions::Nothing)
{
m_queue.erase(find(m_queue.begin(), m_queue.end(), countryId));
m_justDownloaded.insert(countryId);
}
if (!m_queue.empty() && m_downloader->IsIdle())
{
@ -1218,6 +1262,11 @@ void Storage::GetNodeAttrs(TCountryId const & countryId, NodeAttrs & nodeAttrs)
nodeAttrs.m_error = statusAndErr.error;
nodeAttrs.m_nodeLocalName = m_countryNameGetter(countryId);
if (nodeAttrs.m_status == NodeStatus::Downloading)
;
else
nodeAttrs.m_downloadingProgress = 0;
nodeAttrs.m_parentInfo.clear();
nodeAttrs.m_parentInfo.reserve(nodes.size());
for (auto const & n : nodes)

View file

@ -110,6 +110,12 @@ private:
/// can call all the methods from a single thread using
/// RunOnUIThread. If not, at least use a syncronization object.
TQueue m_queue;
/// Set of mwm files which have been downloaded recently.
/// When a mwm file is downloaded it's moved from |m_queue| to |m_justDownloaded|.
/// When a new mwm file is added to |m_queue| |m_justDownloaded| is cleared.
/// Note. This set is necessary for implementation of downloading progress of
/// expandable mwm.
TCountriesUnorderedSet m_justDownloaded;
/// stores countries whose download has failed recently
TCountriesSet m_failedCountries;
@ -172,7 +178,8 @@ private:
string const & dataDir, TMapping * mapping = nullptr);
void ReportProgress(TCountryId const & countryId, pair<int64_t, int64_t> const & p);
void ReportProgressForHierarchy(TCountryId const & countryId, pair<int64_t, int64_t> const & p);
void ReportProgressForHierarchy(TCountryId const & countryId,
pair<int64_t, int64_t> const & leafProgress);
/// Called on the main thread by MapFilesDownloader when list of
/// suitable servers is received.