[storage] Remove redundant template parameters from CountryTree.

This commit is contained in:
tatiana-yan 2019-05-22 14:42:29 +03:00 committed by mpimenov
parent 3a2d66eddb
commit b6c4a59021
12 changed files with 156 additions and 152 deletions

View file

@ -1,6 +1,6 @@
#pragma once
#include "storage/country.hpp"
#include "storage/country_tree.hpp"
#include "storage/storage_defines.hpp"
#include "platform/get_text_by_id.hpp"

View file

@ -1,6 +1,7 @@
#include "search/search_quality/helpers.hpp"
#include "storage/country_info_getter.hpp"
#include "storage/country_tree.hpp"
#include "storage/storage.hpp"
#include "indexer/data_source.hpp"

View file

@ -5,7 +5,6 @@ include_directories(${OMIM_ROOT}/3party/jansson/src)
set(
SRC
app_store.hpp
country.cpp
country.hpp
country_decl.cpp
country_decl.hpp
@ -18,6 +17,7 @@ set(
country_parent_getter.cpp
country_parent_getter.hpp
country_polygon.hpp
country_tree.cpp
country_tree.hpp
diff_scheme/diff_manager.cpp
diff_scheme/diff_manager.hpp

View file

@ -1,7 +1,6 @@
#pragma once
#include "storage/country_decl.hpp"
#include "storage/country_tree.hpp"
#include "storage/storage_defines.hpp"
#include "platform/local_country_file.hpp"
@ -69,16 +68,4 @@ private:
/// If |m_name| is a mwm file name |m_subtreeMwmSizeBytes| is equal to size of the mwm.
MwmSize m_subtreeMwmSizeBytes;
};
using CountryTree = CountryTree<CountryId, Country>;
using CountryTreeNode = CountryTree::Node;
/// @return version of country file or -1 if error was encountered
int64_t LoadCountriesFromBuffer(std::string const & buffer, CountryTree & countries,
Affiliations & affiliations, OldMwmMapping * mapping = nullptr);
int64_t LoadCountriesFromFile(std::string const & path, CountryTree & countries,
Affiliations & affiliations, OldMwmMapping * mapping = nullptr);
void LoadCountryFile2CountryInfo(std::string const & jsonBuffer,
std::map<std::string, CountryInfo> & id2info, bool & isSingleMwm);
} // namespace storage

View file

@ -1,7 +1,7 @@
#include "storage/country_info_getter.hpp"
#include "storage/country.hpp"
#include "storage/country_polygon.hpp"
#include "storage/country_tree.hpp"
#include "platform/local_country_file_utils.hpp"

View file

@ -1,4 +1,4 @@
#include "storage/country.hpp"
#include "storage/country_tree.hpp"
#include "platform/mwm_version.hpp"
#include "platform/platform.hpp"
@ -90,7 +90,9 @@ class StoreFile2InfoSingleMwms : public StoreSingleMwmInterface
map<string, CountryInfo> & m_file2info;
public:
explicit StoreFile2InfoSingleMwms(map<string, CountryInfo> & file2info) : m_file2info(file2info) {}
explicit StoreFile2InfoSingleMwms(map<string, CountryInfo> & file2info) : m_file2info(file2info)
{
}
// StoreSingleMwmInterface overrides:
Country * InsertToCountryTree(CountryId const & id, MwmSize /* mapSize */,
string const & /* mapSha1 */, size_t /* depth */,
@ -223,7 +225,10 @@ class StoreFile2InfoTwoComponentMwms : public StoreTwoComponentMwmInterface
map<string, CountryInfo> & m_file2info;
public:
explicit StoreFile2InfoTwoComponentMwms(map<string, CountryInfo> & file2info) : m_file2info(file2info) {}
explicit StoreFile2InfoTwoComponentMwms(map<string, CountryInfo> & file2info)
: m_file2info(file2info)
{
}
// StoreTwoComponentMwmInterface overrides:
virtual Country * Insert(string const & id, MwmSize mapSize, MwmSize /* routingSize */,
size_t /* depth */, CountryId const & /* parent */) override

View file

@ -1,5 +1,8 @@
#pragma once
#include "storage/country.hpp"
#include "storage/storage_defines.hpp"
#include "base/assert.hpp"
#include <algorithm>
@ -8,15 +11,14 @@
#include <memory>
#include <vector>
namespace storage
{
/// \brief This class is developed for using in Storage. It's a implementation of a tree with
/// ability
/// of access to its nodes in expected constant time with the help of hash table.
/// It should be filled with AddAtDepth method.
/// This class is used in Storage and filled based on countries.txt (countries_migrate.txt).
/// While filling CountryTree nodes in countries.txt should be visited in DFS order.
/// \param TKey is a type of keys to look for |TValue| in |m_countryTreeHashTable|.
/// \param TValue is a type of values which are saved in |m_countryTree| nodes.
template <class TKey, class TValue>
class CountryTree
{
public:
@ -26,28 +28,13 @@ public:
/// While filling Node nodes in countries.txt should be visited in DFS order.
class Node
{
TValue m_value;
/// \brief m_children contains all first generation descendants of the node.
/// Note. Once created the order of elements of |m_children| should not be changed.
/// See implementation of AddAtDepth and Add methods for details.
std::vector<std::unique_ptr<Node>> m_children;
Node * m_parent;
Node * Add(TValue const & value)
{
m_children.emplace_back(std::make_unique<Node>(value, this));
return m_children.back().get();
}
public:
Node(TValue const & value = TValue(), Node * parent = nullptr)
: m_value(value), m_parent(parent)
{
}
using NodeCallback = std::function<void(Node const &)>;
TValue const & Value() const { return m_value; }
TValue & Value() { return m_value; }
Node(Country const & value, Node * parent) : m_value(value), m_parent(parent) {}
Country const & Value() const { return m_value; }
Country & Value() { return m_value; }
/// \brief Adds a node to a tree with root == |this|.
/// \param level is depth where a node with |value| will be add. |level| == 0 means |this|.
@ -58,7 +45,7 @@ public:
/// \param value is a value of node which will be added.
/// \note This method does not let to add a node to an arbitrary place in the tree.
/// It's posible to add children only from "right side".
Node * AddAtDepth(size_t level, TValue const & value)
Node * AddAtDepth(size_t level, Country const & value)
{
Node * node = this;
while (--level > 0 && !node->m_children.empty())
@ -85,24 +72,21 @@ public:
size_t ChildrenCount() const { return m_children.size(); }
/// \brief Calls functor f for each first generation descendant of the node.
template <class TFunctor>
void ForEachChild(TFunctor && f)
/// \brief Calls |f| for each first generation descendant of the node.
void ForEachChild(NodeCallback const & f)
{
for (auto & child : m_children)
f(*child);
}
template <class TFunctor>
void ForEachChild(TFunctor && f) const
void ForEachChild(NodeCallback const & f) const
{
for (auto const & child : m_children)
f(*child);
}
/// \brief Calls functor f for all nodes (add descendant) in the tree.
template <class TFunctor>
void ForEachDescendant(TFunctor && f)
/// \brief Calls |f| for all nodes (add descendant) in the tree.
void ForEachDescendant(NodeCallback const & f)
{
for (auto & child : m_children)
{
@ -111,8 +95,7 @@ public:
}
}
template <class TFunctor>
void ForEachDescendant(TFunctor && f) const
void ForEachDescendant(NodeCallback const & f) const
{
for (auto const & child : m_children)
{
@ -121,24 +104,21 @@ public:
}
}
template <class TFunctor>
void ForEachInSubtree(TFunctor && f)
void ForEachInSubtree(NodeCallback const & f)
{
f(*this);
for (auto & child : m_children)
child->ForEachInSubtree(f);
}
template <class TFunctor>
void ForEachInSubtree(TFunctor && f) const
void ForEachInSubtree(NodeCallback const & f) const
{
f(*this);
for (auto const & child : m_children)
child->ForEachInSubtree(f);
}
template <class TFunctor>
void ForEachAncestorExceptForTheRoot(TFunctor && f)
void ForEachAncestorExceptForTheRoot(NodeCallback const & f)
{
if (m_parent == nullptr || m_parent->m_parent == nullptr)
return;
@ -146,20 +126,30 @@ public:
m_parent->ForEachAncestorExceptForTheRoot(f);
}
template <class TFunctor>
void ForEachAncestorExceptForTheRoot(TFunctor && f) const
void ForEachAncestorExceptForTheRoot(NodeCallback const & f) const
{
if (m_parent == nullptr || m_parent->m_parent == nullptr)
return;
f(*m_parent);
m_parent->ForEachAncestorExceptForTheRoot(f);
}
private:
Node * Add(Country const & value)
{
m_children.emplace_back(std::make_unique<Node>(value, this));
return m_children.back().get();
}
Country m_value;
/// \brief m_children contains all first generation descendants of the node.
/// Note. Once created the order of elements of |m_children| should not be changed.
/// See implementation of AddAtDepth and Add methods for details.
std::vector<std::unique_ptr<Node>> m_children;
Node * m_parent;
};
private:
using CountryTreeHashTable = std::multimap<TKey, Node *>;
public:
bool IsEmpty() const { return m_countryTree == nullptr; }
Node const & GetRoot() const
@ -174,7 +164,7 @@ public:
return *m_countryTree;
}
TValue & AddAtDepth(size_t level, TValue const & value)
Country & AddAtDepth(size_t level, Country const & value)
{
Node * added = nullptr;
if (level == 0)
@ -203,7 +193,7 @@ public:
/// \brief Checks all nodes in tree to find an equal one. If there're several equal nodes
/// returns the first found.
/// \returns a poiter item in the tree if found and nullptr otherwise.
void Find(TKey const & key, std::vector<Node const *> & found) const
void Find(CountryId const & key, std::vector<Node const *> & found) const
{
found.clear();
if (IsEmpty())
@ -222,7 +212,7 @@ public:
});
}
Node const * const FindFirst(TKey const & key) const
Node const * const FindFirst(CountryId const & key) const
{
if (IsEmpty())
return nullptr;
@ -239,7 +229,7 @@ public:
/// When new countries.txt with unique ids will be added FindLeaf will be removed
/// and Find will be used intead.
/// @TODO(bykoianko) Remove this method on countries.txt update.
Node const * const FindFirstLeaf(TKey const & key) const
Node const * const FindFirstLeaf(CountryId const & key) const
{
if (IsEmpty())
return nullptr;
@ -256,6 +246,18 @@ public:
}
private:
using CountryTreeHashTable = std::multimap<CountryId, Node *>;
std::unique_ptr<Node> m_countryTree;
CountryTreeHashTable m_countryTreeHashTable;
};
/// @return version of country file or -1 if error was encountered
int64_t LoadCountriesFromBuffer(std::string const & buffer, CountryTree & countries,
Affiliations & affiliations, OldMwmMapping * mapping = nullptr);
int64_t LoadCountriesFromFile(std::string const & path, CountryTree & countries,
Affiliations & affiliations, OldMwmMapping * mapping = nullptr);
void LoadCountryFile2CountryInfo(std::string const & jsonBuffer,
std::map<std::string, CountryInfo> & id2info, bool & isSingleMwm);
} // namespace storage

View file

@ -69,9 +69,10 @@ void DeleteFromDiskWithIndexes(LocalCountryFile const & localFile, MapOptions op
localFile.DeleteFromDisk(options);
}
CountryTreeNode const & LeafNodeFromCountryId(CountryTree const & root, CountryId const & countryId)
CountryTree::Node const & LeafNodeFromCountryId(CountryTree const & root,
CountryId const & countryId)
{
CountryTreeNode const * node = root.FindFirstLeaf(countryId);
CountryTree::Node const * node = root.FindFirstLeaf(countryId);
CHECK(node, ("Node with id =", countryId, "not found in country tree as a leaf."));
return *node;
}
@ -359,7 +360,7 @@ Country const & Storage::CountryLeafByCountryId(CountryId const & countryId) con
Country const & Storage::CountryByCountryId(CountryId const & countryId) const
{
CountryTreeNode const * node = m_countries.FindFirst(countryId);
CountryTree::Node const * node = m_countries.FindFirst(countryId);
CHECK(node, ("Node with id =", countryId, "not found in country tree."));
return node->Value();
}
@ -375,7 +376,7 @@ bool Storage::IsLeaf(CountryId const & countryId) const
{
if (!IsCountryIdValid(countryId))
return false;
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
return node != nullptr && node->ChildrenCount() == 0;
}
@ -383,7 +384,7 @@ bool Storage::IsInnerNode(CountryId const & countryId) const
{
if (!IsCountryIdValid(countryId))
return false;
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
return node != nullptr && node->ChildrenCount() != 0;
}
@ -624,9 +625,10 @@ void Storage::NotifyStatusChangedForHierarchy(CountryId const & countryId)
NotifyStatusChanged(countryId);
// Notification status changing for ancestors in country tree.
ForEachAncestorExceptForTheRoot(
countryId,
[&](CountryId const & parentId, CountryTreeNode const &) { NotifyStatusChanged(parentId); });
ForEachAncestorExceptForTheRoot(countryId,
[&](CountryId const & parentId, CountryTree::Node const &) {
NotifyStatusChanged(parentId);
});
}
void Storage::DownloadNextCountryFromQueue()
@ -852,9 +854,9 @@ void Storage::ReportProgressForHierarchy(CountryId const & countryId,
CountriesSet setQueue;
GetQueuedCountries(m_queue, setQueue);
auto calcProgress = [&](CountryId const & parentId, CountryTreeNode const & parentNode) {
auto calcProgress = [&](CountryId const & parentId, CountryTree::Node const & parentNode) {
CountriesVec descendants;
parentNode.ForEachDescendant([&descendants](CountryTreeNode const & container) {
parentNode.ForEachDescendant([&descendants](CountryTree::Node const & container) {
descendants.push_back(container.Value().Name());
});
@ -1378,7 +1380,7 @@ void Storage::GetChildren(CountryId const & parent, CountriesVec & childIds) con
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
CountryTreeNode const * const parentNode = m_countries.FindFirst(parent);
CountryTree::Node const * const parentNode = m_countries.FindFirst(parent);
if (parentNode == nullptr)
{
ASSERT(false, ("CountryId =", parent, "not found in m_countries."));
@ -1408,7 +1410,7 @@ void Storage::GetChildrenInGroups(CountryId const & parent, CountriesVec & downl
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
CountryTreeNode const * const parentNode = m_countries.FindFirst(parent);
CountryTree::Node const * const parentNode = m_countries.FindFirst(parent);
if (parentNode == nullptr)
{
ASSERT(false, ("CountryId =", parent, "not found in m_countries."));
@ -1424,7 +1426,7 @@ void Storage::GetChildrenInGroups(CountryId const & parent, CountriesVec & downl
CountriesVec disputedTerritoriesWithoutSiblings;
// All disputed territories in subtree with root == |parent|.
CountriesVec allDisputedTerritories;
parentNode->ForEachChild([&](CountryTreeNode const & childNode) {
parentNode->ForEachChild([&](CountryTree::Node const & childNode) {
vector<pair<CountryId, NodeStatus>> disputedTerritoriesAndStatus;
StatusAndError const childStatus = GetNodeStatusInfo(childNode, disputedTerritoriesAndStatus,
true /* isDisputedTerritoriesCounted */);
@ -1494,7 +1496,7 @@ void Storage::DownloadNode(CountryId const & countryId, bool isUpdate /* = false
LOG(LINFO, ("Downloading", countryId));
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
if (!node)
return;
@ -1502,7 +1504,7 @@ void Storage::DownloadNode(CountryId const & countryId, bool isUpdate /* = false
if (GetNodeStatus(*node).status == NodeStatus::OnDisk)
return;
auto downloadAction = [this, isUpdate](CountryTreeNode const & descendantNode) {
auto downloadAction = [this, isUpdate](CountryTree::Node const & descendantNode) {
if (descendantNode.ChildrenCount() == 0 &&
GetNodeStatus(descendantNode).status != NodeStatus::OnDisk)
this->DownloadCountry(descendantNode.Value().Name(),
@ -1516,12 +1518,12 @@ void Storage::DeleteNode(CountryId const & countryId)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
if (!node)
return;
auto deleteAction = [this](CountryTreeNode const & descendantNode) {
auto deleteAction = [this](CountryTree::Node const & descendantNode) {
bool onDisk = m_localFiles.find(descendantNode.Value().Name()) != m_localFiles.end();
if (descendantNode.ChildrenCount() == 0 && onDisk)
this->DeleteCountry(descendantNode.Value().Name(), MapOptions::MapWithCarRouting);
@ -1529,15 +1531,15 @@ void Storage::DeleteNode(CountryId const & countryId)
node->ForEachInSubtree(deleteAction);
}
StatusAndError Storage::GetNodeStatus(CountryTreeNode const & node) const
StatusAndError Storage::GetNodeStatus(CountryTree::Node const & node) const
{
vector<pair<CountryId, NodeStatus>> disputedTerritories;
return GetNodeStatusInfo(node, disputedTerritories, false /* isDisputedTerritoriesCounted */);
}
bool Storage::IsDisputed(CountryTreeNode const & node) const
bool Storage::IsDisputed(CountryTree::Node const & node) const
{
vector<CountryTreeNode const *> found;
vector<CountryTree::Node const *> found;
m_countries.Find(node.Value().Name(), found);
return found.size() > 1;
}
@ -1715,7 +1717,7 @@ void Storage::OnDiffStatusReceived(diffs::Status const status)
DoDeferredDownloadIfNeeded();
}
StatusAndError Storage::GetNodeStatusInfo(CountryTreeNode const & node,
StatusAndError Storage::GetNodeStatusInfo(CountryTree::Node const & node,
vector<pair<CountryId, NodeStatus>> & disputedTerritories,
bool isDisputedTerritoriesCounted) const
{
@ -1732,7 +1734,7 @@ StatusAndError Storage::GetNodeStatusInfo(CountryTreeNode const & node,
NodeStatus result = NodeStatus::NotDownloaded;
bool allOnDisk = true;
auto groupStatusCalculator = [&](CountryTreeNode const & nodeInSubtree) {
auto groupStatusCalculator = [&](CountryTree::Node const & nodeInSubtree) {
StatusAndError const statusAndError =
ParseStatus(CountryStatusEx(nodeInSubtree.Value().Name()));
@ -1766,13 +1768,13 @@ void Storage::GetNodeAttrs(CountryId const & countryId, NodeAttrs & nodeAttrs) c
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
vector<CountryTreeNode const *> nodes;
vector<CountryTree::Node const *> nodes;
m_countries.Find(countryId, nodes);
CHECK(!nodes.empty(), (countryId));
// If nodes.size() > 1 countryId corresponds to a disputed territories.
// In that case it's guaranteed that most of attributes are equal for
// each element of nodes. See Country class description for further details.
CountryTreeNode const * const node = nodes[0];
CountryTree::Node const * const node = nodes[0];
Country const & nodeValue = node->Value();
nodeAttrs.m_mwmCounter = nodeValue.GetSubtreeMwmCounter();
@ -1796,7 +1798,7 @@ void Storage::GetNodeAttrs(CountryId const & countryId, NodeAttrs & nodeAttrs) c
{
CountriesVec subtree;
node->ForEachInSubtree(
[&subtree](CountryTreeNode const & d) { subtree.push_back(d.Value().Name()); });
[&subtree](CountryTree::Node const & d) { subtree.push_back(d.Value().Name()); });
CountryId const & downloadingMwm =
IsDownloadInProgress() ? GetCurrentDownloadingCountryId() : kInvalidCountryId;
MapFilesDownloader::Progress downloadingMwmProgress(0, 0);
@ -1820,7 +1822,7 @@ void Storage::GetNodeAttrs(CountryId const & countryId, NodeAttrs & nodeAttrs) c
nodeAttrs.m_downloadingMwmCounter = 0;
nodeAttrs.m_downloadingMwmSize = 0;
CountriesSet visitedLocalNodes;
node->ForEachInSubtree([this, &nodeAttrs, &visitedLocalNodes](CountryTreeNode const & d) {
node->ForEachInSubtree([this, &nodeAttrs, &visitedLocalNodes](CountryTree::Node const & d) {
CountryId const countryId = d.Value().Name();
if (visitedLocalNodes.count(countryId) != 0)
return;
@ -1863,7 +1865,7 @@ void Storage::GetNodeAttrs(CountryId const & countryId, NodeAttrs & nodeAttrs) c
// Parents country.
nodeAttrs.m_topmostParentInfo.clear();
ForEachAncestorExceptForTheRoot(
nodes, [&](CountryId const & ancestorId, CountryTreeNode const & node) {
nodes, [&](CountryId const & ancestorId, CountryTree::Node const & node) {
if (node.Value().GetParent() == GetRootId())
nodeAttrs.m_topmostParentInfo.push_back({ancestorId, m_countryNameGetter(ancestorId)});
});
@ -1873,7 +1875,7 @@ void Storage::GetNodeStatuses(CountryId const & countryId, NodeStatuses & nodeSt
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
CHECK(node, (countryId));
StatusAndError statusAndErr = GetNodeStatus(*node);
@ -1976,7 +1978,7 @@ void Storage::RetryDownloadNode(CountryId const & countryId)
bool Storage::GetUpdateInfo(CountryId const & countryId, UpdateInfo & updateInfo) const
{
auto const updateInfoAccumulator = [&updateInfo, this](CountryTreeNode const & node) {
auto const updateInfoAccumulator = [&updateInfo, this](CountryTree::Node const & node) {
if (node.ChildrenCount() != 0 || GetNodeStatus(node).status != NodeStatus::OnDiskOutOfDate)
return;
@ -1998,7 +2000,7 @@ bool Storage::GetUpdateInfo(CountryId const & countryId, UpdateInfo & updateInfo
static_cast<int64_t>(sizes.second) - static_cast<int64_t>(sizes.first);
};
CountryTreeNode const * const node = m_countries.FindFirst(countryId);
CountryTree::Node const * const node = m_countries.FindFirst(countryId);
if (!node)
{
ASSERT(false, ());
@ -2024,7 +2026,7 @@ void Storage::PopFromQueue(Queue::iterator it)
void Storage::GetQueuedChildren(CountryId const & parent, CountriesVec & queuedChildren) const
{
CountryTreeNode const * const node = m_countries.FindFirst(parent);
CountryTree::Node const * const node = m_countries.FindFirst(parent);
if (!node)
{
ASSERT(false, ());
@ -2032,7 +2034,7 @@ void Storage::GetQueuedChildren(CountryId const & parent, CountriesVec & queuedC
}
queuedChildren.clear();
node->ForEachChild([&queuedChildren, this](CountryTreeNode const & child) {
node->ForEachChild([&queuedChildren, this](CountryTree::Node const & child) {
NodeStatus status = GetNodeStatus(child).status;
ASSERT_NOT_EQUAL(status, NodeStatus::Undefined, ());
if (status == NodeStatus::Downloading || status == NodeStatus::InQueue)
@ -2044,7 +2046,7 @@ void Storage::GetGroupNodePathToRoot(CountryId const & groupNode, CountriesVec &
{
path.clear();
vector<CountryTreeNode const *> nodes;
vector<CountryTree::Node const *> nodes;
m_countries.Find(groupNode, nodes);
if (nodes.empty())
{
@ -2065,7 +2067,7 @@ void Storage::GetGroupNodePathToRoot(CountryId const & groupNode, CountriesVec &
}
ForEachAncestorExceptForTheRoot(
nodes, [&path](CountryId const & id, CountryTreeNode const &) { path.push_back(id); });
nodes, [&path](CountryId const & id, CountryTree::Node const &) { path.push_back(id); });
path.push_back(m_countries.GetRoot().Value().Name());
}
@ -2074,7 +2076,7 @@ void Storage::GetTopmostNodesFor(CountryId const & countryId, CountriesVec & nod
{
nodes.clear();
vector<CountryTreeNode const *> treeNodes;
vector<CountryTree::Node const *> treeNodes;
m_countries.Find(countryId, treeNodes);
if (treeNodes.empty())
{
@ -2089,7 +2091,7 @@ void Storage::GetTopmostNodesFor(CountryId const & countryId, CountriesVec & nod
CountriesVec path;
ForEachAncestorExceptForTheRoot(
{treeNodes[i]},
[&path](CountryId const & id, CountryTreeNode const &) { path.emplace_back(id); });
[&path](CountryId const & id, CountryTree::Node const &) { path.emplace_back(id); });
if (!path.empty() && level < path.size())
nodes[i] = path[path.size() - 1 - level];
}
@ -2097,7 +2099,7 @@ void Storage::GetTopmostNodesFor(CountryId const & countryId, CountriesVec & nod
CountryId const Storage::GetParentIdFor(CountryId const & countryId) const
{
vector<CountryTreeNode const *> nodes;
vector<CountryTree::Node const *> nodes;
m_countries.Find(countryId, nodes);
if (nodes.empty())
{

View file

@ -668,11 +668,11 @@ private:
Status CountryStatus(CountryId const & countryId) const;
/// Returns status for a node (group node or not).
StatusAndError GetNodeStatus(CountryTreeNode const & node) const;
StatusAndError GetNodeStatus(CountryTree::Node const & node) const;
/// Returns status for a node (group node or not).
/// Fills |disputedTeritories| with all disputed teritories in subtree with the root == |node|.
StatusAndError GetNodeStatusInfo(
CountryTreeNode const & node,
CountryTree::Node const & node,
std::vector<std::pair<CountryId, NodeStatus>> & disputedTeritories,
bool isDisputedTerritoriesCounted) const;
@ -700,11 +700,11 @@ private:
void PopFromQueue(Queue::iterator it);
template <class ToDo>
void ForEachAncestorExceptForTheRoot(std::vector<CountryTreeNode const *> const & nodes,
void ForEachAncestorExceptForTheRoot(std::vector<CountryTree::Node const *> const & nodes,
ToDo && toDo) const;
/// Returns true if |node.Value().Name()| is a disputed territory and false otherwise.
bool IsDisputed(CountryTreeNode const & node) const;
bool IsDisputed(CountryTree::Node const & node) const;
void CalcMaxMwmSizeBytes();
@ -727,13 +727,13 @@ void GetQueuedCountries(Storage::Queue const & queue, CountriesSet & resultCount
template <class ToDo>
void Storage::ForEachInSubtree(CountryId const & root, ToDo && toDo) const
{
CountryTreeNode const * const rootNode = m_countries.FindFirst(root);
CountryTree::Node const * const rootNode = m_countries.FindFirst(root);
if (rootNode == nullptr)
{
ASSERT(false, ("CountryId =", root, "not found in m_countries."));
return;
}
rootNode->ForEachInSubtree([&toDo](CountryTreeNode const & container) {
rootNode->ForEachInSubtree([&toDo](CountryTree::Node const & container) {
Country const & value = container.Value();
toDo(value.Name(), value.GetSubtreeMwmCounter() != 1 /* groupNode. */);
});
@ -749,7 +749,7 @@ void Storage::ForEachInSubtree(CountryId const & root, ToDo && toDo) const
template <class ToDo>
void Storage::ForEachAncestorExceptForTheRoot(CountryId const & countryId, ToDo && toDo) const
{
std::vector<CountryTreeNode const *> nodes;
std::vector<CountryTree::Node const *> nodes;
m_countries.Find(countryId, nodes);
if (nodes.empty())
{
@ -761,15 +761,15 @@ void Storage::ForEachAncestorExceptForTheRoot(CountryId const & countryId, ToDo
}
template <class ToDo>
void Storage::ForEachAncestorExceptForTheRoot(std::vector<CountryTreeNode const *> const & nodes,
void Storage::ForEachAncestorExceptForTheRoot(std::vector<CountryTree::Node const *> const & nodes,
ToDo && toDo) const
{
std::set<CountryTreeNode const *> visitedAncestors;
std::set<CountryTree::Node const *> visitedAncestors;
// In most cases nodes.size() == 1. In case of disputable territories nodes.size()
// may be more than one. It means |childId| is present in the country tree more than once.
for (auto const & node : nodes)
{
node->ForEachAncestorExceptForTheRoot([&](CountryTreeNode const & container) {
node->ForEachAncestorExceptForTheRoot([&](CountryTree::Node const & container) {
CountryId const ancestorId = container.Value().Name();
if (visitedAncestors.find(&container) != visitedAncestors.end())
return; // The node was visited before because countryId is present in the tree more

View file

@ -4,57 +4,56 @@
namespace
{
template <class TNode>
template <class Node>
struct Calculator
{
size_t count;
Calculator() : count(0) {}
void operator()(TNode const &)
{
++count;
}
void operator()(Node const &) { ++count; }
};
} // namespace
UNIT_TEST(CountryTree_Smoke)
{
typedef CountryTree<int, int>::Node TTree;
TTree tree(0, nullptr);
using Tree = storage::CountryTree::Node;
using Value = storage::Country;
tree.AddAtDepth(1, 4);
tree.AddAtDepth(1, 3);
tree.AddAtDepth(1, 5);
tree.AddAtDepth(1, 2);
tree.AddAtDepth(1, 1);
tree.AddAtDepth(2, 20);
tree.AddAtDepth(2, 10);
tree.AddAtDepth(2, 30);
Tree tree(Value("0"), nullptr);
tree.AddAtDepth(1, Value("4"));
tree.AddAtDepth(1, Value("3"));
tree.AddAtDepth(1, Value("5"));
tree.AddAtDepth(1, Value("2"));
tree.AddAtDepth(1, Value("1"));
tree.AddAtDepth(2, Value("20"));
tree.AddAtDepth(2, Value("10"));
tree.AddAtDepth(2, Value("30"));
// children test
TEST_EQUAL(tree.Child(0).Value(), 4, ());
TEST_EQUAL(tree.Child(1).Value(), 3, ());
TEST_EQUAL(tree.Child(2).Value(), 5, ());
TEST_EQUAL(tree.Child(3).Value(), 2, ());
TEST_EQUAL(tree.Child(4).Value(), 1, ());
TEST_EQUAL(tree.Child(4).Child(0).Value(), 20, ());
TEST_EQUAL(tree.Child(4).Child(1).Value(), 10, ());
TEST_EQUAL(tree.Child(4).Child(2).Value(), 30, ());
TEST_EQUAL(tree.Child(0).Value().Name(), "4", ());
TEST_EQUAL(tree.Child(1).Value().Name(), "3", ());
TEST_EQUAL(tree.Child(2).Value().Name(), "5", ());
TEST_EQUAL(tree.Child(3).Value().Name(), "2", ());
TEST_EQUAL(tree.Child(4).Value().Name(), "1", ());
TEST_EQUAL(tree.Child(4).Child(0).Value().Name(), "20", ());
TEST_EQUAL(tree.Child(4).Child(1).Value().Name(), "10", ());
TEST_EQUAL(tree.Child(4).Child(2).Value().Name(), "30", ());
// parent test
TEST(!tree.HasParent(), ());
TEST(!tree.Child(0).Parent().HasParent(), ());
TEST_EQUAL(tree.Child(4).Child(0).Parent().Value(), 1, ());
TEST_EQUAL(tree.Child(4).Child(2).Parent().Value(), 1, ());
TEST_EQUAL(tree.Child(4).Child(0).Parent().Value().Name(), "1", ());
TEST_EQUAL(tree.Child(4).Child(2).Parent().Value().Name(), "1", ());
Calculator<TTree> c1;
Calculator<Tree> c1;
tree.ForEachChild(c1);
TEST_EQUAL(c1.count, 5, ());
Calculator<TTree> c2;
Calculator<Tree> c2;
tree.ForEachDescendant(c2);
TEST_EQUAL(c2.count, 8, ());
Calculator<TTree> c3;
Calculator<Tree> c3;
tree.Child(4).Child(0).ForEachAncestorExceptForTheRoot(c3);
TEST_EQUAL(c3.count, 1, ());
}

View file

@ -1504,9 +1504,9 @@ UNIT_TEST(StorageTest_ForEachAncestorExceptForTheRoot)
// Two parent case.
auto const forEachParentDisputableTerritory = [](CountryId const & parentId,
CountryTreeNode const & parentNode) {
CountryTree::Node const & parentNode) {
CountriesVec descendants;
parentNode.ForEachDescendant([&descendants](CountryTreeNode const & container) {
parentNode.ForEachDescendant([&descendants](CountryTree::Node const & container) {
descendants.push_back(container.Value().Name());
});
@ -1530,9 +1530,9 @@ UNIT_TEST(StorageTest_ForEachAncestorExceptForTheRoot)
// One parent case.
auto const forEachParentIndisputableTerritory = [](CountryId const & parentId,
CountryTreeNode const & parentNode) {
CountryTree::Node const & parentNode) {
CountriesVec descendants;
parentNode.ForEachDescendant([&descendants](CountryTreeNode const & container) {
parentNode.ForEachDescendant([&descendants](CountryTree::Node const & container) {
descendants.push_back(container.Value().Name());
});

View file

@ -22,6 +22,9 @@
3DCD414920D80C1B00143533 /* lightweight_matching_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DCD414820D80C1B00143533 /* lightweight_matching_tests.cpp */; };
401ECED41F56C50900DFDF76 /* country_parent_getter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 401ECED21F56C50900DFDF76 /* country_parent_getter.cpp */; };
401ECED51F56C50900DFDF76 /* country_parent_getter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 401ECED31F56C50900DFDF76 /* country_parent_getter.hpp */; };
402873422295A91F0036AA1C /* country_tree.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4028733F2295A91E0036AA1C /* country_tree.hpp */; };
402873432295A91F0036AA1C /* country_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 402873402295A91F0036AA1C /* country_tree.cpp */; };
402873442295A91F0036AA1C /* downloader_search_params.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 402873412295A91F0036AA1C /* downloader_search_params.hpp */; };
4586D0C71F48126A00DF9CE5 /* diff_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4586D0C51F48126A00DF9CE5 /* diff_manager.cpp */; };
4586D0C81F48126A00DF9CE5 /* diff_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4586D0C61F48126A00DF9CE5 /* diff_manager.hpp */; };
5670EAFA1FF1150C002495D8 /* libtransit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5670EAFB1FF1150C002495D8 /* libtransit.a */; };
@ -58,7 +61,6 @@
675343091A3F5A2600A0A8C3 /* country_decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675342F21A3F5A2600A0A8C3 /* country_decl.cpp */; };
6753430A1A3F5A2600A0A8C3 /* country_decl.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675342F31A3F5A2600A0A8C3 /* country_decl.hpp */; };
6753430D1A3F5A2600A0A8C3 /* country_polygon.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675342F61A3F5A2600A0A8C3 /* country_polygon.hpp */; };
6753430E1A3F5A2600A0A8C3 /* country.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675342F71A3F5A2600A0A8C3 /* country.cpp */; };
6753430F1A3F5A2600A0A8C3 /* country.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675342F81A3F5A2600A0A8C3 /* country.hpp */; };
675343191A3F5A2600A0A8C3 /* storage_defines.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675343021A3F5A2600A0A8C3 /* storage_defines.hpp */; };
6753431A1A3F5A2600A0A8C3 /* storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675343031A3F5A2600A0A8C3 /* storage.cpp */; };
@ -208,6 +210,9 @@
3DCD414820D80C1B00143533 /* lightweight_matching_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lightweight_matching_tests.cpp; sourceTree = "<group>"; };
401ECED21F56C50900DFDF76 /* country_parent_getter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = country_parent_getter.cpp; sourceTree = "<group>"; };
401ECED31F56C50900DFDF76 /* country_parent_getter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_parent_getter.hpp; sourceTree = "<group>"; };
4028733F2295A91E0036AA1C /* country_tree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_tree.hpp; sourceTree = "<group>"; };
402873402295A91F0036AA1C /* country_tree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = country_tree.cpp; sourceTree = "<group>"; };
402873412295A91F0036AA1C /* downloader_search_params.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = downloader_search_params.hpp; sourceTree = "<group>"; };
4069AD9F21495A5A005EB75C /* categories_cuisines.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = categories_cuisines.txt; sourceTree = "<group>"; };
4586D0C51F48126A00DF9CE5 /* diff_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = diff_manager.cpp; path = diff_scheme/diff_manager.cpp; sourceTree = "<group>"; };
4586D0C61F48126A00DF9CE5 /* diff_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = diff_manager.hpp; path = diff_scheme/diff_manager.hpp; sourceTree = "<group>"; };
@ -282,7 +287,6 @@
675342F21A3F5A2600A0A8C3 /* country_decl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = country_decl.cpp; sourceTree = "<group>"; };
675342F31A3F5A2600A0A8C3 /* country_decl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_decl.hpp; sourceTree = "<group>"; };
675342F61A3F5A2600A0A8C3 /* country_polygon.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_polygon.hpp; sourceTree = "<group>"; };
675342F71A3F5A2600A0A8C3 /* country.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = country.cpp; sourceTree = "<group>"; };
675342F81A3F5A2600A0A8C3 /* country.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country.hpp; sourceTree = "<group>"; };
675343021A3F5A2600A0A8C3 /* storage_defines.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = storage_defines.hpp; sourceTree = "<group>"; };
675343031A3F5A2600A0A8C3 /* storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = storage.cpp; sourceTree = "<group>"; };
@ -566,6 +570,9 @@
675342E21A3F59EF00A0A8C3 /* storage */ = {
isa = PBXGroup;
children = (
402873402295A91F0036AA1C /* country_tree.cpp */,
4028733F2295A91E0036AA1C /* country_tree.hpp */,
402873412295A91F0036AA1C /* downloader_search_params.hpp */,
3DCD414520D80C0900143533 /* country_info_reader_light.cpp */,
3DCD414420D80C0800143533 /* country_info_reader_light.hpp */,
F6BC312A2034366100F677FE /* pinger.cpp */,
@ -597,7 +604,6 @@
675342F21A3F5A2600A0A8C3 /* country_decl.cpp */,
675342F31A3F5A2600A0A8C3 /* country_decl.hpp */,
675342F61A3F5A2600A0A8C3 /* country_polygon.hpp */,
675342F71A3F5A2600A0A8C3 /* country.cpp */,
675342F81A3F5A2600A0A8C3 /* country.hpp */,
675343021A3F5A2600A0A8C3 /* storage_defines.hpp */,
675343031A3F5A2600A0A8C3 /* storage.cpp */,
@ -666,11 +672,13 @@
678338D61C723B1A00FD6263 /* helpers.hpp in Headers */,
67247FCF1C60BA8A00EDE56A /* fake_map_files_downloader.hpp in Headers */,
67AF4A011BC579DD0048B1ED /* country_info_getter.hpp in Headers */,
402873442295A91F0036AA1C /* downloader_search_params.hpp in Headers */,
674125221B4C05FA00A3E828 /* queued_country.hpp in Headers */,
6753431B1A3F5A2600A0A8C3 /* storage.hpp in Headers */,
67247FD61C60BA8A00EDE56A /* test_map_files_downloader.hpp in Headers */,
4586D0C81F48126A00DF9CE5 /* diff_manager.hpp in Headers */,
34B093231C61F9BA0066F4C3 /* storage_helpers.hpp in Headers */,
402873422295A91F0036AA1C /* country_tree.hpp in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -836,7 +844,6 @@
56D8CB991CAC17A80003F420 /* test_defines.cpp in Sources */,
401ECED41F56C50900DFDF76 /* country_parent_getter.cpp in Sources */,
56D0E4811F8E40340084B18C /* routing_helpers.cpp in Sources */,
6753430E1A3F5A2600A0A8C3 /* country.cpp in Sources */,
67AF4A001BC579DD0048B1ED /* country_info_getter.cpp in Sources */,
34B093221C61F9BA0066F4C3 /* storage_helpers.cpp in Sources */,
4586D0C71F48126A00DF9CE5 /* diff_manager.cpp in Sources */,
@ -850,6 +857,7 @@
3DCD414920D80C1B00143533 /* lightweight_matching_tests.cpp in Sources */,
67BE1DC51CD2180D00572709 /* downloading_policy.cpp in Sources */,
678338D41C723B1A00FD6263 /* country_name_getter_test.cpp in Sources */,
402873432295A91F0036AA1C /* country_tree.cpp in Sources */,
F6BC312C2034366100F677FE /* pinger.cpp in Sources */,
34C9BCFC1C6CCF85000DC38D /* country_name_getter.cpp in Sources */,
6741251E1B4C05FA00A3E828 /* http_map_files_downloader.cpp in Sources */,