diff --git a/storage/diff_scheme/diff_manager.cpp b/storage/diff_scheme/diff_manager.cpp index 8d5254973f..29c0580494 100644 --- a/storage/diff_scheme/diff_manager.cpp +++ b/storage/diff_scheme/diff_manager.cpp @@ -23,7 +23,7 @@ void Manager::Load(LocalMapsInfo && info) m_workerThread.Push([this, localMapsInfo] { - NameFileInfoMap const diffs = Checker::Check(localMapsInfo); + NameDiffInfoMap const diffs = Checker::Check(localMapsInfo); std::lock_guard lock(m_mutex); @@ -82,9 +82,9 @@ void Manager::ApplyDiff(ApplyDiffParams && p, std::function lock(m_mutex); - m_diffs.erase(diffFile->GetCountryName()); - if (m_diffs.empty()) - m_status = Status::NotAvailable; + auto it = m_diffs.find(diffFile->GetCountryName()); + CHECK(it != m_diffs.end(), ()); + it->second.m_applied = true; } else { @@ -109,17 +109,32 @@ Status Manager::GetStatus() const bool Manager::SizeFor(storage::TCountryId const & countryId, uint64_t & size) const { - return WithDiff(countryId, [&size](FileInfo const & info) { size = info.m_size; }); + return WithDiff(countryId, [&size](DiffInfo const & info) { size = info.m_size; }); } bool Manager::VersionFor(storage::TCountryId const & countryId, uint64_t & version) const { - return WithDiff(countryId, [&version](FileInfo const & info) { version = info.m_version; }); + return WithDiff(countryId, [&version](DiffInfo const & info) { version = info.m_version; }); } bool Manager::HasDiffFor(storage::TCountryId const & countryId) const { - return WithDiff(countryId, [](FileInfo const &){}); + return WithDiff(countryId, [](DiffInfo const &){}); +} + +void Manager::RemoveAppliedDiffs() +{ + std::lock_guard lock(m_mutex); + for (auto it = m_diffs.begin(); it != m_diffs.end();) + { + if (it->second.m_applied) + it = m_diffs.erase(it); + else + ++it; + } + + if (m_diffs.empty()) + m_status = Status::NotAvailable; } bool Manager::IsPossibleToAutoupdate() const diff --git a/storage/diff_scheme/diff_manager.hpp b/storage/diff_scheme/diff_manager.hpp index 130b6c1d6c..9a54a9b536 100644 --- a/storage/diff_scheme/diff_manager.hpp +++ b/storage/diff_scheme/diff_manager.hpp @@ -37,6 +37,7 @@ public: bool VersionFor(storage::TCountryId const & countryId, uint64_t & version) const; bool IsPossibleToAutoupdate() const; bool HasDiffFor(storage::TCountryId const & countryId) const; + void RemoveAppliedDiffs(); Status GetStatus() const; @@ -64,7 +65,7 @@ private: mutable std::mutex m_mutex; Status m_status = Status::Undefined; - NameFileInfoMap m_diffs; + NameDiffInfoMap m_diffs; LocalMapsInfo m_localMapsInfo; base::ObserverListUnsafe m_observers; base::WorkerThread m_workerThread; diff --git a/storage/diff_scheme/diff_scheme_checker.cpp b/storage/diff_scheme/diff_scheme_checker.cpp index 148f757b1a..e1ac43044a 100644 --- a/storage/diff_scheme/diff_scheme_checker.cpp +++ b/storage/diff_scheme/diff_scheme_checker.cpp @@ -47,30 +47,30 @@ string SerializeCheckerData(LocalMapsInfo const & info) return buffer.get(); } -NameFileInfoMap DeserializeResponse(string const & response, LocalMapsInfo::NameVersionMap const & nameVersionMap) +NameDiffInfoMap DeserializeResponse(string const & response, LocalMapsInfo::NameVersionMap const & nameVersionMap) { if (response.empty()) { LOG(LERROR, ("Diff response shouldn't be empty.")); - return NameFileInfoMap{}; + return NameDiffInfoMap{}; } my::Json const json(response.c_str()); if (json.get() == nullptr) - return NameFileInfoMap{}; + return NameDiffInfoMap{}; auto const root = json_object_get(json.get(), kMwmsKey); if (root == nullptr || !json_is_array(root)) - return NameFileInfoMap{}; + return NameDiffInfoMap{}; auto const size = json_array_size(root); if (size == 0 || size != nameVersionMap.size()) { LOG(LERROR, ("Diff list size in response must be equal to mwm list size in request.")); - return NameFileInfoMap{}; + return NameDiffInfoMap{}; } - NameFileInfoMap diffs; + NameDiffInfoMap diffs; for (size_t i = 0; i < size; ++i) { @@ -79,7 +79,7 @@ NameFileInfoMap DeserializeResponse(string const & response, LocalMapsInfo::Name if (!node) { LOG(LERROR, ("Incorrect server response.")); - return NameFileInfoMap{}; + return NameDiffInfoMap{}; } string name; @@ -93,10 +93,10 @@ NameFileInfoMap DeserializeResponse(string const & response, LocalMapsInfo::Name if (nameVersionMap.find(name) == nameVersionMap.end()) { LOG(LERROR, ("Incorrect country name in response:", name)); - return NameFileInfoMap{}; + return NameDiffInfoMap{}; } - FileInfo info(size, nameVersionMap.at(name)); + DiffInfo info(size, nameVersionMap.at(name)); diffs.emplace(move(name), move(info)); } @@ -109,17 +109,17 @@ namespace storage namespace diffs { //static -NameFileInfoMap Checker::Check(LocalMapsInfo const & info) +NameDiffInfoMap Checker::Check(LocalMapsInfo const & info) { if (info.m_localMaps.empty()) - return NameFileInfoMap(); + return NameDiffInfoMap(); platform::HttpClient request(DIFF_LIST_URL); string const body = SerializeCheckerData(info); ASSERT(!body.empty(), ()); request.SetBodyData(body, "application/json"); request.SetTimeout(kTimeoutInSeconds); - NameFileInfoMap diffs; + NameDiffInfoMap diffs; if (request.RunHttpRequest() && !request.WasRedirected() && request.ErrorCode() == 200) { diffs = DeserializeResponse(request.ServerResponse(), info.m_localMaps); diff --git a/storage/diff_scheme/diff_scheme_checker.hpp b/storage/diff_scheme/diff_scheme_checker.hpp index a12c75b85c..2cd69dcb25 100644 --- a/storage/diff_scheme/diff_scheme_checker.hpp +++ b/storage/diff_scheme/diff_scheme_checker.hpp @@ -9,7 +9,7 @@ namespace diffs class Checker final { public: - static NameFileInfoMap Check(LocalMapsInfo const & info); + static NameDiffInfoMap Check(LocalMapsInfo const & info); }; } // namespace diffs } // namespace storage diff --git a/storage/diff_scheme/diff_types.hpp b/storage/diff_scheme/diff_types.hpp index dc3a515ee2..0020ef90e0 100644 --- a/storage/diff_scheme/diff_types.hpp +++ b/storage/diff_scheme/diff_types.hpp @@ -15,14 +15,15 @@ enum class Status Available }; -struct FileInfo final +struct DiffInfo final { - FileInfo(uint64_t size, uint64_t version) : m_size(size), m_version(version) {} + DiffInfo(uint64_t size, uint64_t version) : m_size(size), m_version(version) {} uint64_t m_size; uint64_t m_version; + bool m_applied = false; }; -using NameFileInfoMap = std::unordered_map; +using NameDiffInfoMap = std::unordered_map; struct LocalMapsInfo final { diff --git a/storage/storage.cpp b/storage/storage.cpp index 8d0d02134e..ee434e349b 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -573,6 +573,7 @@ void Storage::DownloadNextCountryFromQueue() if (m_queue.empty()) { + m_diffManager.RemoveAppliedDiffs(); m_downloadingPolicy->ScheduleRetry(m_failedCountries, [this](TCountriesSet const & needReload) { for (auto const & country : needReload) {