dbms: added function regionToTopContinent [#METR-19807].

This commit is contained in:
Alexey Milovidov 2016-02-01 23:18:13 +03:00
parent 14854540ba
commit 477c7245d4
3 changed files with 34 additions and 5 deletions

View File

@ -54,8 +54,10 @@ private:
RegionParents area;
/// регион -> округ, включающий его или 0, если такого нет
RegionParents district;
/// регион -> континет, включающий его или 0, если такого нет
/// регион -> континет (первый при подъёме по иерархии регионов), включающий его или 0, если такого нет
RegionParents continent;
/// регион -> континет (последний при подъёме по иерархии регионов), включающий его или 0, если такого нет
RegionParents top_continent;
/// регион -> население или 0, если неизвестно.
RegionPopulations populations;
@ -88,6 +90,7 @@ public:
RegionParents new_area(initial_size);
RegionParents new_district(initial_size);
RegionParents new_continent(initial_size);
RegionParents new_top_continent(initial_size);
RegionPopulations new_populations(initial_size);
RegionDepths new_depths(initial_size);
RegionTypes types(initial_size);
@ -151,6 +154,7 @@ public:
new_area .resize(max_region_id + 1);
new_district .resize(max_region_id + 1);
new_continent .resize(max_region_id + 1);
new_top_continent.resize(max_region_id + 1);
new_populations .resize(max_region_id + 1);
new_depths .resize(max_region_id + 1);
types .resize(max_region_id + 1);
@ -173,7 +177,7 @@ public:
if (types[i] == REGION_TYPE_CONTINENT)
{
new_continent[i] = i;
continue;
new_top_continent[i] = i;
}
RegionDepth depth = 0;
@ -203,8 +207,9 @@ public:
if (types[current] == REGION_TYPE_CONTINENT)
{
new_continent[i] = current;
break;
if (!new_continent[i])
new_continent[i] = current;
new_top_continent[i] = current;
}
}
@ -217,6 +222,7 @@ public:
area.swap(new_area);
district.swap(new_district);
continent.swap(new_continent);
top_continent.swap(new_top_continent);
populations.swap(new_populations);
depths.swap(new_depths);
}
@ -268,6 +274,13 @@ public:
return continent[region];
}
RegionID toTopContinent(RegionID region) const
{
if (static_cast<size_t>(region) >= top_continent.size())
return 0;
return top_continent[region];
}
RegionID toParent(RegionID region) const
{
if (static_cast<size_t>(region) >= parents.size())

View File

@ -38,7 +38,7 @@ namespace ErrorCodes
* - словари регионов, операционных систем, поисковых систем.
*
* Подняться по дереву до определенного уровня.
* regionToCity, regionToArea, regionToCountry,
* regionToCity, regionToArea, regionToCountry, ...
* OSToRoot,
* SEToRoot,
*
@ -91,6 +91,11 @@ struct RegionToContinentImpl
static UInt32 apply(UInt32 x, const RegionsHierarchy & hierarchy) { return hierarchy.toContinent(x); }
};
struct RegionToTopContinentImpl
{
static UInt32 apply(UInt32 x, const RegionsHierarchy & hierarchy) { return hierarchy.toTopContinent(x); }
};
struct RegionToPopulationImpl
{
static UInt32 apply(UInt32 x, const RegionsHierarchy & hierarchy) { return hierarchy.getPopulation(x); }
@ -513,6 +518,7 @@ struct NameRegionToArea { static constexpr auto name = "regionToArea"; };
struct NameRegionToDistrict { static constexpr auto name = "regionToDistrict"; };
struct NameRegionToCountry { static constexpr auto name = "regionToCountry"; };
struct NameRegionToContinent { static constexpr auto name = "regionToContinent"; };
struct NameRegionToTopContinent { static constexpr auto name = "regionToTopContinent"; };
struct NameRegionToPopulation { static constexpr auto name = "regionToPopulation"; };
struct NameOSToRoot { static constexpr auto name = "OSToRoot"; };
struct NameSEToRoot { static constexpr auto name = "SEToRoot"; };
@ -571,6 +577,15 @@ struct FunctionRegionToContinent :
}
};
struct FunctionRegionToTopContinent :
public FunctionTransformWithDictionary<UInt32, RegionToTopContinentImpl, RegionsHierarchyGetter, NameRegionToTopContinent>
{
static IFunction * create(const Context & context)
{
return new base_type{context.getDictionaries().getRegionsHierarchies()};
}
};
struct FunctionRegionToPopulation :
public FunctionTransformWithDictionary<UInt32, RegionToPopulationImpl, RegionsHierarchyGetter, NameRegionToPopulation>
{

View File

@ -11,6 +11,7 @@ void registerFunctionsDictionaries(FunctionFactory & factory)
factory.registerFunction<FunctionRegionToDistrict>();
factory.registerFunction<FunctionRegionToCountry>();
factory.registerFunction<FunctionRegionToContinent>();
factory.registerFunction<FunctionRegionToTopContinent>();
factory.registerFunction<FunctionRegionToPopulation>();
factory.registerFunction<FunctionOSToRoot>();
factory.registerFunction<FunctionSEToRoot>();