From 0ecbf94dc2ce3998f84f8472d712a20c4893099d Mon Sep 17 00:00:00 2001 From: Constantin Shalnev Date: Wed, 10 Feb 2016 19:18:09 +0300 Subject: [PATCH] [new downloader] Storage class has been made less messy --- storage/storage.cpp | 1 - storage/storage.hpp | 77 +++++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/storage/storage.cpp b/storage/storage.cpp index 2e36c7651d..92978f91f8 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -410,7 +410,6 @@ void Storage::RestoreDownloadQueue() } } - void Storage::DownloadCountry(TCountryId const & countryId, MapOptions opt) { if (opt == MapOptions::Nothing) diff --git a/storage/storage.hpp b/storage/storage.hpp index b03024298e..21e40b156f 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -24,16 +24,17 @@ struct NodeAttrs NodeAttrs() : m_mwmCounter(0), m_localMwmCounter(0), m_mwmSize(0), m_localMwmSize(0), m_downloadingMwmSize(0), m_downloadingProgress(0), m_status(NodeStatus::Undefined), m_error(NodeErrorCode::NoError) {} + /// If the node is expandable (a big country) |m_mwmCounter| is number of mwm files (leaves) - /// belongs to the node. If the node isn't expandable |m_mwmCounter| == 1. + /// belonging to the node. If the node isn't expandable |m_mwmCounter| == 1. /// Note. For every expandable node |m_mwmCounter| >= 2. uint32_t m_mwmCounter; - /// Number of mwms belonging to the node which has been donwloaded. + /// Number of mwms belonging to the node which have been donwloaded. uint32_t m_localMwmCounter; - /// If it's not an expandable node, |m_nodeSize| is size of one mwm according to countries.txt. - /// Otherwise |m_nodeSize| is the sum of all mwm file sizes which belong to the group + /// If it's not an expandable node, |m_mwmSize| is size of one mwm according to countries.txt. + /// Otherwise |m_mwmSize| is the sum of all mwm file sizes which belong to the group /// according to countries.txt. size_t m_mwmSize; @@ -182,10 +183,13 @@ public: /// * download some maps to WritableDir/|dataDir| /// * destroy the instance of Storage and move the downloaded maps to proper place Storage(string const & pathToCountriesFile = COUNTRIES_FILE, string const & dataDir = string()); + /// \brief This constructor should be used for testing only. Storage(string const & referenceCountriesTxtJsonForTesting, unique_ptr mapDownloaderForTesting); + void Init(TUpdate const & update); + /// @name Interface with clients (Android/iOS). /// \brief It represents the interface which can be used by clients (Android/iOS). /// The term node means an mwm or a group of mwm like a big country. @@ -213,9 +217,11 @@ public: /// \brief Returns root country id of the county tree. TCountryId const GetRootId() const; + /// \param childrenId is filled with children node ids by a parent. For example GetChildren(GetRootId()) /// returns in param all countries ids. It's content of map downloader list by default. void GetChildren(TCountryId const & parent, TCountriesVec & childrenId) const; + /// \brief Fills localChildren with children of parent. /// The result of the method is composed in a special way because of design requirements. /// If a direct child (of parent) contains two or more downloaded mwms the direct child id will be added to result. @@ -226,6 +232,7 @@ public: /// the method does not put to localChildren neither custom maps generated by user /// nor World.mwm and WorldCoasts.mwm. void GetDownloadedChildren(TCountryId const & parent, TCountriesVec & localChildren) const; + /// \brief Gets list of available countries. /// \param countryList is filled with a list of node id which an end user will see in /// a list of available maps. They are all available countries expect for fully downloaded @@ -234,6 +241,7 @@ public: /// \brief Returns current version for mwms which are available on the server. inline int64_t GetCurrentDataVersion() const { return m_currentVersion; } + /// \brief Returns true if the node with countryId has been downloaded and false othewise. /// If countryId is a expandable returns true if all mwms which belongs to it have downloaded. /// Returns false if countryId is an unknown string. @@ -249,16 +257,20 @@ public: /// If node is expandable downloads all children (grandchildren) by the node /// until they havn't been downloaded before. Update all downloaded mwm if it's necessary. bool DownloadNode(TCountryId const & countryId); + /// \brief Delete one node (expandable or not). bool DeleteNode(TCountryId const & countryId); + /// \brief Updates one node (expandable or not). /// \note If you want to update all the maps and this update is without changing /// borders or hierarchy just call UpdateNode(GetRootId()). /// \return false in case of error and true otherwise. - bool UpdateNode(TCountryId const & countryId); + bool UpdateNode(TCountryId const & countryId) { return true; } + /// \brief Cancels downloading a node if the downloading is in process. /// \return false in case of error and true otherwise. bool CancelDownloadNode(TCountryId const & countryId) { return true; } + /// \brief Downloading process could be interupted because of bad internet connection. /// In that case user could want to recover it. This method is done for it. /// This method works with expandable and not expandable countryId. @@ -267,46 +279,37 @@ public: /// \brief Shows a node (expandable or not) on the map. /// \return false in case of error and true otherwise. - bool ShowNode(TCountryId const & countryId); + bool ShowNode(TCountryId const & countryId) { return true; } /// \brief Get information for mwm update button. /// \return true if updateInfo is filled correctly and false otherwise. bool GetUpdateInfo(TCountryId const & countryId, UpdateInfo & updateInfo) const { return true; } + /// \brief Update all mwm in case of changing mwm hierarchy of mwm borders. /// This method: /// * removes all mwms /// * downloads mwms with the same coverage /// \note This method is used in very rare case. /// \return false in case of error and true otherwise. - bool UpdateAllAndChangeHierarchy(); + bool UpdateAllAndChangeHierarchy() { return true; } /// \brief Calls |toDo| for each node for subtree with |root|. /// For example ForEachInSubtree(GetRootId()) calls |toDo| for every node including /// the result of GetRootId() call. template - void ForEachInSubtree(TCountryId const & root, ToDo && toDo) const - { - TCountriesContainer const * const rootNode = m_countries.Find(Country(root)); - if (rootNode == nullptr) - { - ASSERT(false, ("TCountryId =", root, "not found in m_countries.")); - return; - } - rootNode->ForEachInSubtree([&toDo](TCountriesContainer const & countryContainer) - { - Country const & value = countryContainer.Value(); - toDo(value.Name(), value.GetSubtreeMwmCounter() != 1 /* expandableNode. */); - }); - } + void ForEachInSubtree(TCountryId const & root, ToDo && toDo) const; /// \brief Subscribe on change status callback. /// \returns a unique index of added status callback structure. - size_t SubscribeStatusCallback(StatusCallback const & statusCallbacks); + size_t SubscribeStatusCallback(StatusCallback const & statusCallbacks) { return 0; } + /// \brief Unsubscribe from change status callback. /// \param index is a unique index of callback retruned by SubscribeStatusCallback. - void UnsubscribeStatusCallback(size_t index); + void UnsubscribeStatusCallback(size_t index) {} + /// \brief Sets callback which will be called in case of a click on download map button on the map. - void SetCallbackForClickOnDownloadMap(TDownloadFn & downloadFn) { m_downloadMapOnTheMap = downloadFn; } + void SetCallbackForClickOnDownloadMap(TDownloadFn & downloadFn) { m_downloadMapOnTheMap = downloadFn; } + /// \brief Calls |m_downloadMapOnTheMap| if one has been set. /// \param |countryId| is country id of a leaf. That means it's a file name. /// \note This method should be called for a click of download map button @@ -318,8 +321,6 @@ public: /// So this method does not return custom user local maps and World and WorldCoosts country id. void GetLocalRealMaps(TCountriesVec & localMaps) const; - void Init(TUpdate const & update); - /// Do we have downloaded countries bool HaveDownloadedCountries() const; @@ -330,7 +331,6 @@ public: void SaveDownloadQueue(); void RestoreDownloadQueue(); - /// Delete local maps and aggregate their Id if needed void DeleteAllLocalMaps(TCountriesVec * existedCountries = nullptr); @@ -349,6 +349,7 @@ public: // Returns list of all local maps, including fake countries (World*.mwm). void GetLocalMaps(vector & maps) const; + // Returns number of downloaded maps (files), excluding fake countries (World*.mwm). size_t GetDownloadedFilesCount() const; @@ -360,9 +361,11 @@ public: Country const & CountryByCountryId(TCountryId const & countryId) const; TCountryId FindCountryIdByFile(string const & name) const; + /// @todo Temporary function to gel all associated indexes for the country file name. /// Will be removed in future after refactoring. TCountriesVec FindAllIndexesByFile(string const & name) const; + void GetGroupAndCountry(TCountryId const & countryId, string & group, string & country) const; size_t CountriesCount(TCountryId const & countryId) const; @@ -401,12 +404,14 @@ public: /// get download url by countryId & options(first search file name by countryId, then format url) string GetFileDownloadUrl(string const & baseUrl, TCountryId const & countryId, MapOptions file) const; + /// get download url by base url & file name string GetFileDownloadUrl(string const & baseUrl, string const & fName) const; /// @param[out] res Populated with oudated countries. void GetOutdatedCountries(vector & countries) const; + // for testing: void SetDownloaderForTesting(unique_ptr && downloader); void SetCurrentDataVersionForTesting(int64_t currentVersion); void SetDownloadingUrlsForTesting(vector const & downloadingUrls) @@ -470,11 +475,29 @@ private: string GetFileDownloadPath(TCountryId const & countryId, MapOptions file) const; void CountryStatusEx(TCountryId const & countryId, Status & status, MapOptions & options) const; + /// Fast version, doesn't check if country is out of date Status CountryStatus(TCountryId const & countryId) const; + /// Returns status for a node (group node or not) Status NodeStatus(TCountriesContainer const & node) const; }; +template +void Storage::ForEachInSubtree(TCountryId const & root, ToDo && toDo) const +{ + TCountriesContainer const * const rootNode = m_countries.Find(Country(root)); + if (rootNode == nullptr) + { + ASSERT(false, ("TCountryId =", root, "not found in m_countries.")); + return; + } + rootNode->ForEachInSubtree([&toDo](TCountriesContainer const & countryContainer) + { + Country const & value = countryContainer.Value(); + toDo(value.Name(), value.GetSubtreeMwmCounter() != 1 /* expandableNode. */); + }); +} + bool HasCountryId(TCountriesVec const & sorted, TCountryId const & countyId); } // storage