diff --git a/storage/country.cpp b/storage/country.cpp index bdb8962881..3b29b1f7fe 100644 --- a/storage/country.cpp +++ b/storage/country.cpp @@ -19,7 +19,7 @@ namespace storage using TMwmSubtreeAttrs = pair; template -TMwmSubtreeAttrs LoadGroupSingleMwmsImpl(int depth, json_t * group, ToDo & toDo) +TMwmSubtreeAttrs LoadGroupSingleMwmsImpl(int depth, json_t * group, ToDo & toDo, TCountryId const & parent) { uint32_t mwmCounter = 0; size_t mwmSize = 0; @@ -34,7 +34,7 @@ TMwmSubtreeAttrs LoadGroupSingleMwmsImpl(int depth, json_t * group, ToDo & toDo) uint32_t const nodeSize = static_cast(json_integer_value(json_object_get(j, "s"))); // We expect that mwm and routing files should be less than 2GB. - Country * addedNode = toDo(id, nodeSize, depth); + Country * addedNode = toDo(id, nodeSize, depth, parent); json_t * oldIds = json_object_get(j, "old"); if (oldIds) @@ -52,7 +52,7 @@ TMwmSubtreeAttrs LoadGroupSingleMwmsImpl(int depth, json_t * group, ToDo & toDo) json_t * children = json_object_get(j, "g"); if (children) { - TMwmSubtreeAttrs childAttr = LoadGroupSingleMwmsImpl(depth + 1, children, toDo); + TMwmSubtreeAttrs childAttr = LoadGroupSingleMwmsImpl(depth + 1, children, toDo, id); mwmChildCounter = childAttr.first; mwmChildSize = childAttr.second; } @@ -71,7 +71,7 @@ TMwmSubtreeAttrs LoadGroupSingleMwmsImpl(int depth, json_t * group, ToDo & toDo) } template -void LoadGroupTwoComponentMwmsImpl(int depth, json_t * group, ToDo & toDo) +void LoadGroupTwoComponentMwmsImpl(int depth, json_t * group, ToDo & toDo, TCountryId const & parent) { // @TODO(bykoianko) After we stop supporting two component mwms (with routing files) // remove code below. @@ -92,16 +92,16 @@ void LoadGroupTwoComponentMwmsImpl(int depth, json_t * group, ToDo & toDo) // We expect that mwm and routing files should be less than 2GB. toDo(file, static_cast(json_integer_value(json_object_get(j, "s"))), - static_cast(json_integer_value(json_object_get(j, "rs"))), depth); + static_cast(json_integer_value(json_object_get(j, "rs"))), depth, parent); json_t * children = json_object_get(j, "g"); if (children) - LoadGroupTwoComponentMwmsImpl(depth + 1, children, toDo); + LoadGroupTwoComponentMwmsImpl(depth + 1, children, toDo, file); } } template -bool LoadCountriesSingleMwmsImpl(string const & jsonBuffer, ToDo & toDo) +bool LoadCountriesSingleMwmsImpl(string const & jsonBuffer, ToDo & toDo, TCountryId const & parent) { try { @@ -109,7 +109,7 @@ bool LoadCountriesSingleMwmsImpl(string const & jsonBuffer, ToDo & toDo) json_t * children = json_object_get(root.get(), "g"); if (!children) MYTHROW(my::Json::Exception, ("Root country doesn't have any groups")); - TMwmSubtreeAttrs const treeAttrs = LoadGroupSingleMwmsImpl(0, children, toDo); + TMwmSubtreeAttrs const treeAttrs = LoadGroupSingleMwmsImpl(0, children, toDo, parent); toDo.SetCountriesContainerAttrs(treeAttrs.first /* mwmNumber */, treeAttrs.second /* mwmSizeBytes */); return true; @@ -122,7 +122,7 @@ bool LoadCountriesSingleMwmsImpl(string const & jsonBuffer, ToDo & toDo) } template -bool LoadCountriesTwoComponentMwmsImpl(string const & jsonBuffer, ToDo & toDo) +bool LoadCountriesTwoComponentMwmsImpl(string const & jsonBuffer, ToDo & toDo, TCountryId const & parent) { try { @@ -130,7 +130,7 @@ bool LoadCountriesTwoComponentMwmsImpl(string const & jsonBuffer, ToDo & toDo) json_t * children = json_object_get(root.get(), "g"); if (!children) MYTHROW(my::Json::Exception, ("Root country doesn't have any groups")); - LoadGroupTwoComponentMwmsImpl(0, children, toDo); + LoadGroupTwoComponentMwmsImpl(0, children, toDo, parent); return true; } catch (my::Json::Exception const & e) @@ -150,9 +150,9 @@ class DoStoreCountriesSingleMwms public: DoStoreCountriesSingleMwms(TCountriesContainer & cont) : m_cont(cont) {} - Country * operator()(string const & id, uint32_t mapSize, int depth) + Country * operator()(string const & id, uint32_t mapSize, int depth, TCountryId const & parent) { - Country country(id); + Country country(id, parent); if (mapSize) { CountryFile countryFile(id); @@ -183,9 +183,9 @@ public: DoStoreCountriesTwoComponentMwms(TCountriesContainer & cont) : m_cont(cont) {} void operator()(string const & file, uint32_t mapSize, - uint32_t routingSize, int depth) + uint32_t routingSize, int depth, TCountryId const & parent) { - Country country(file); + Country country(file, parent); if (mapSize) { CountryFile countryFile(file); @@ -205,7 +205,8 @@ public: DoStoreFile2InfoSingleMwms(map & file2info) : m_file2info(file2info) {} - Country * operator()(string const & id, uint32_t /* mapSize */, int /* depth */) + Country * operator()(string const & id, uint32_t /* mapSize */, int /* depth */, + TCountryId const & /* parent */) { CountryInfo info(id); m_file2info[id] = move(info); @@ -230,7 +231,8 @@ public: DoStoreFile2InfoTwoComponentMwms(map & file2info) : m_file2info(file2info) {} - void operator()(string const & id, uint32_t mapSize, uint32_t /* routingSize */, int /* depth */) + void operator()(string const & id, uint32_t mapSize, uint32_t /* routingSize */, int /* depth */, + TCountryId const & /* parent */) { if (mapSize == 0) return; @@ -258,14 +260,14 @@ int64_t LoadCountries(string const & jsonBuffer, TCountriesContainer & countries char const * id = json_string_value(json_object_get(rootPtr, idKey)); if (!id) MYTHROW(my::Json::Exception, ("LoadCountries. Id is missing.", id)); - Country rootCountry(id); + Country rootCountry(id, kInvalidCountryId); // @TODO(bykoianko) Add CourtyFile to rootCountry with correct size. countries.Value() = rootCountry; if (isSingleMwm) { DoStoreCountriesSingleMwms doStore(countries); - if (!LoadCountriesSingleMwmsImpl(jsonBuffer, doStore)) + if (!LoadCountriesSingleMwmsImpl(jsonBuffer, doStore, id)) return -1; if (mapping) *mapping = doStore.GetMapping(); @@ -273,7 +275,7 @@ int64_t LoadCountries(string const & jsonBuffer, TCountriesContainer & countries else { DoStoreCountriesTwoComponentMwms doStore(countries); - if (!LoadCountriesTwoComponentMwmsImpl(jsonBuffer, doStore)) + if (!LoadCountriesTwoComponentMwmsImpl(jsonBuffer, doStore, id)) return -1; } } @@ -298,12 +300,12 @@ void LoadCountryFile2CountryInfo(string const & jsonBuffer, map; class Country { friend class update::SizeUpdater; - /// Name in the country node tree + /// Name in the country node tree. In single mwm case it's a country id. TCountryId m_name; + /// Country id of parent of m_name in country tree. m_parent == kInvalidCountryId for the root. + TCountryId m_parent; /// |m_file| is a CountryFile of mwm with id == |m_name|. /// if |m_name| is node id of a group of mwms, |m_file| is empty. platform::CountryFile m_file; @@ -43,7 +45,8 @@ class Country public: Country() = default; - Country(TCountryId const & name) : m_name(name) {} + explicit Country(TCountryId const & name, TCountryId const & parent = kInvalidCountryId) + : m_name(name), m_parent(parent) {} bool operator<(Country const & other) const { return Name() < other.Name(); } void SetFile(platform::CountryFile const & file) { m_file = file; } @@ -54,6 +57,7 @@ public: } uint32_t GetSubtreeMwmCounter() const { return m_subtreeMwmNumber; } size_t GetSubtreeMwmSizeBytes() const { return m_subtreeMwmSizeBytes; } + TCountryId GetParent() const { return m_parent; } /// This function valid for current logic - one file for one country (region). /// If the logic will be changed, replace GetFile with ForEachFile. diff --git a/storage/storage.cpp b/storage/storage.cpp index e8608de2e8..bac6147567 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -766,7 +766,7 @@ TCountriesVec Storage::FindAllIndexesByFile(string const & name) const // @TODO(bykoianko) This method should be rewritten. At list now name and the param of Find // have different types: string and TCountryId. TCountriesVec result; - if (m_countries.Find(name)) + if (m_countries.Find(Country(name))) result.push_back(name); return result; } @@ -976,7 +976,7 @@ TCountryId const Storage::GetRootId() const void Storage::GetChildren(TCountryId const & parent, TCountriesVec & childrenId) const { - TCountriesContainer const * parentNode = m_countries.Find(parent); + TCountriesContainer const * parentNode = m_countries.Find(Country(parent)); if (parentNode == nullptr) { ASSERT(false, ("TCountryId =", parent, "not found in m_countries.")); @@ -1001,7 +1001,7 @@ void Storage::GetLocalRealMaps(TCountriesVec & localMaps) const void Storage::GetDownloadedChildren(TCountryId const & parent, TCountriesVec & localChildren) const { - TCountriesContainer const * parentNode = m_countries.Find(parent); + TCountriesContainer const * parentNode = m_countries.Find(Country(parent)); if (parentNode == nullptr) { ASSERT(false, ("TCountryId =", parent, "not found in m_countries.")); @@ -1069,7 +1069,7 @@ bool Storage::DownloadNode(TCountryId const & countryId) { // @TODO(bykoianko) Before downloading it's necessary to check if file(s) has been downloaded. // If so, the method should be left with false. - TCountriesContainer const * const node = m_countries.Find(countryId); + TCountriesContainer const * const node = m_countries.Find(Country(countryId)); CHECK(node, ()); node->ForEachInSubtree([this](TCountriesContainer const & descendantNode) { @@ -1086,7 +1086,7 @@ bool Storage::DeleteNode(TCountryId const & countryId) { // @TODO(bykoianko) Before deleting it's necessary to check if file(s) has been deleted. // If so, the method should be left with false. - TCountriesContainer const * const node = m_countries.Find(countryId); + TCountriesContainer const * const node = m_countries.Find(Country(countryId)); CHECK(node, ()); node->ForEachInSubtree([this](TCountriesContainer const & descendantNode) { @@ -1124,7 +1124,7 @@ Status Storage::NodeStatus(TCountriesContainer const & node) const void Storage::GetNodeAttrs(TCountryId const & countryId, NodeAttrs & nodeAttrs) const { - TCountriesContainer const * const node = m_countries.Find(countryId); + TCountriesContainer const * const node = m_countries.Find(Country(countryId)); CHECK(node, ()); Country const & nodeValue = node->Value();