ClickHouse/dbms/Dictionaries/Embedded/RegionsHierarchy.h

131 lines
3.5 KiB
C++
Raw Normal View History

#pragma once
#include <vector>
#include <boost/noncopyable.hpp>
#include <common/types.h>
#include "GeodataProviders/IHierarchiesProvider.h"
class IRegionsHierarchyDataProvider;
2017-04-17 11:56:55 +00:00
/** A class that lets you know if a region belongs to one RegionID region with another RegionID.
* Information about the hierarchy of regions is downloaded from a text file.
* Can on request update the data.
*/
class RegionsHierarchy : private boost::noncopyable
{
private:
2017-04-17 11:56:55 +00:00
/// Relationship parent; 0, if there are no parents, the usual lookup table.
using RegionParents = std::vector<RegionID>;
2017-04-17 11:56:55 +00:00
/// type of region
using RegionTypes = std::vector<RegionType>;
2017-04-17 11:56:55 +00:00
/// depth in the tree, starting from the country (country: 1, root: 0)
using RegionDepths = std::vector<RegionDepth>;
2017-04-17 11:56:55 +00:00
/// population of the region. If more than 2 ^ 32 - 1, then it is equated to this maximum.
using RegionPopulations = std::vector<RegionPopulation>;
2017-04-17 11:56:55 +00:00
/// region -> parent region
RegionParents parents;
2017-04-17 11:56:55 +00:00
/// region -> city, including it or 0, if there is none
RegionParents city;
2017-04-17 11:56:55 +00:00
/// region -> country including it or 0, if there is none
RegionParents country;
2017-04-17 11:56:55 +00:00
/// region -> area that includes it or 0, if not
RegionParents area;
2017-04-17 11:56:55 +00:00
/// region -> district, including it or 0, if there is none
RegionParents district;
2017-04-17 11:56:55 +00:00
/// region -> the continent (the first when climbing in the hierarchy of regions), including it or 0, if there is none
RegionParents continent;
2017-04-17 11:56:55 +00:00
/// region -> the continent (the latter when you climb the hierarchy of regions), including it or 0, if there is none
RegionParents top_continent;
2017-04-17 11:56:55 +00:00
/// region -> population or 0, if unknown.
RegionPopulations populations;
2017-04-17 11:56:55 +00:00
/// region - depth in the tree
RegionDepths depths;
IRegionsHierarchyDataSourcePtr data_source;
public:
RegionsHierarchy(IRegionsHierarchyDataSourcePtr data_source_);
2017-04-17 11:56:55 +00:00
/// Reloads, if necessary, the hierarchy of regions. Not threadsafe.
void reload();
bool in(RegionID lhs, RegionID rhs) const
{
if (lhs >= parents.size())
return false;
while (lhs != 0 && lhs != rhs)
lhs = parents[lhs];
return lhs != 0;
}
RegionID toCity(RegionID region) const
{
if (region >= city.size())
return 0;
return city[region];
}
RegionID toCountry(RegionID region) const
{
if (region >= country.size())
return 0;
return country[region];
}
RegionID toArea(RegionID region) const
{
if (region >= area.size())
return 0;
return area[region];
}
RegionID toDistrict(RegionID region) const
{
if (region >= district.size())
return 0;
return district[region];
}
RegionID toContinent(RegionID region) const
{
if (region >= continent.size())
return 0;
return continent[region];
}
RegionID toTopContinent(RegionID region) const
{
if (region >= top_continent.size())
return 0;
return top_continent[region];
}
RegionID toParent(RegionID region) const
{
if (region >= parents.size())
return 0;
return parents[region];
}
RegionDepth getDepth(RegionID region) const
{
if (region >= depths.size())
return 0;
return depths[region];
}
RegionPopulation getPopulation(RegionID region) const
{
if (region >= populations.size())
return 0;
return populations[region];
}
};