Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
130
libs/storage/country_tree.hpp
Normal file
130
libs/storage/country_tree.hpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
|
||||
#include "storage/country.hpp"
|
||||
#include "storage/storage_defines.hpp"
|
||||
|
||||
#include "base/buffer_vector.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#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.
|
||||
class CountryTree
|
||||
{
|
||||
public:
|
||||
/// This class is developed for using in CountryTree. It's a implementation of a tree.
|
||||
/// It should be filled with AddAtDepth method.
|
||||
/// This class is used in filled based on countries.txt (countries_migrate.txt).
|
||||
/// While filling Node nodes in countries.txt should be visited in DFS order.
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
using NodeCallback = std::function<void(Node const &)>;
|
||||
|
||||
Node(Country && value, Node * parent) : m_value(std::move(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|.
|
||||
/// When the method is called the node |this| exists. So it's wrong call it with |level| == 0.
|
||||
/// If |level| == 1 the node with |value| will be added as a child of this.
|
||||
/// If |level| == 2 the node with |value| will be added as a child of the last added child of the |this|.
|
||||
/// And so on.
|
||||
/// \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, Country && value);
|
||||
|
||||
bool HasParent() const { return m_parent != nullptr; }
|
||||
|
||||
bool IsRoot() const { return !HasParent(); }
|
||||
|
||||
Node const & Parent() const;
|
||||
|
||||
Node const & Child(size_t index) const;
|
||||
|
||||
size_t ChildrenCount() const { return m_children.size(); }
|
||||
|
||||
/// \brief Calls |f| for each first generation descendant of the node.
|
||||
void ForEachChild(NodeCallback const & f);
|
||||
|
||||
void ForEachChild(NodeCallback const & f) const;
|
||||
|
||||
/// \brief Calls |f| for all nodes (add descendant) in the tree.
|
||||
void ForEachDescendant(NodeCallback const & f);
|
||||
|
||||
void ForEachDescendant(NodeCallback const & f) const;
|
||||
|
||||
void ForEachInSubtree(NodeCallback const & f);
|
||||
|
||||
void ForEachInSubtree(NodeCallback const & f) const;
|
||||
|
||||
void ForEachAncestorExceptForTheRoot(NodeCallback const & f);
|
||||
|
||||
void ForEachAncestorExceptForTheRoot(NodeCallback const & f) const;
|
||||
|
||||
private:
|
||||
Node * Add(Country && value);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
bool IsEmpty() const { return m_countryTree == nullptr; }
|
||||
|
||||
Node const & GetRoot() const;
|
||||
|
||||
Node & GetRoot();
|
||||
|
||||
Country & AddAtDepth(size_t level, Country && value);
|
||||
|
||||
/// Deletes all children and makes tree empty
|
||||
void Clear();
|
||||
|
||||
using NodesBufferT = buffer_vector<Node const *, 4>;
|
||||
/// \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(CountryId const & key, NodesBufferT & found) const;
|
||||
|
||||
Node const * FindFirst(CountryId const & key) const;
|
||||
|
||||
/// \brief Find only leaves.
|
||||
/// \note It's a termprary fucntion for compatablity with old countries.txt.
|
||||
/// 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 * FindFirstLeaf(CountryId const & key) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Node> m_countryTree;
|
||||
std::multimap<CountryId, Node *> m_countryTreeMap;
|
||||
};
|
||||
|
||||
/// @return version of country file or -1 if error was encountered
|
||||
int64_t LoadCountriesFromBuffer(std::string const & buffer, CountryTree & countries, Affiliations & affiliations,
|
||||
CountryNameSynonyms & countryNameSynonyms, MwmTopCityGeoIds & mwmTopCityGeoIds,
|
||||
MwmTopCountryGeoIds & mwmTopCountryGeoIds);
|
||||
int64_t LoadCountriesFromFile(std::string const & path, CountryTree & countries, Affiliations & affiliations,
|
||||
CountryNameSynonyms & countryNameSynonyms, MwmTopCityGeoIds & mwmTopCityGeoIds,
|
||||
MwmTopCountryGeoIds & mwmTopCountryGeoIds);
|
||||
|
||||
void LoadCountryFile2CountryInfo(std::string const & jsonBuffer, std::map<std::string, CountryInfo> & id2info);
|
||||
} // namespace storage
|
||||
Loading…
Add table
Add a link
Reference in a new issue