minor fixes

This commit is contained in:
Anton Popov 2020-07-29 04:32:23 +03:00
parent 6d58279535
commit 48e6253442
6 changed files with 26 additions and 28 deletions

View File

@ -56,9 +56,9 @@ LAYOUT(POLYGON())
Пользователь может [загружать свои собственные данные](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md) во всех поддерживаемых ClickHouse форматах.
Доступно 3 типа [хранения данных в памяти](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md): (TODO: время, память)
Доступно 3 типа [хранения данных в памяти](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md):
- POLYGON. Это наивная реализация, в которой на каждый запрос делается линейный проход по всем полигонам, и для каждого проверяется принадлежность без использования дополнительных индексов.
- POLYGON_SIMPLE. Это наивная реализация, в которой на каждый запрос делается линейный проход по всем полигонам, и для каждого проверяется принадлежность без использования дополнительных индексов.
- POLYGON_INDEX_EACH. Для каждого полигона строится отдельный индекс, который позволяет быстро проверять принадлежность в большинстве случаев (оптимизирован под географические регионы).
Также на рассматриваемую область накладывается сетка, которая значительно сужает количество рассматриваемых полигонов.
@ -68,6 +68,7 @@ LAYOUT(POLYGON())
- POLYGON_INDEX_CELL. В этом размещении также строится сетка, описанная выше. Доступны такие же параметры. Для каждой ячейки-листа строится индекс на всех попадающих в неё кусках полигонов, который позволяет быстро отвечать на запрос.
- POLYGON. Синоним к POLYGON_INDEX_CELL.
Запросы к словарю осуществляются с помощью стандартных [функций](../../../sql-reference/functions/ext-dict-functions.md) для работы со внешними словарями.
Важным отличием является то, что здесь ключами будут являются точки, для которых хочется найти содержащий их полигон.

View File

@ -244,9 +244,12 @@ DictionaryPtr createLayout(const std::string & ,
void registerDictionaryPolygon(DictionaryFactory & factory)
{
factory.registerLayout("polygon", createLayout<PolygonDictionarySimple>, true);
factory.registerLayout("polygon_simple", createLayout<PolygonDictionarySimple>, true);
factory.registerLayout("polygon_index_each", createLayout<PolygonDictionaryIndexEach>, true);
factory.registerLayout("polygon_index_cell", createLayout<PolygonDictionaryIndexCell>, true);
/// Alias to the most performant dictionary type - polygon_index_cell
factory.registerLayout("polygon", createLayout<PolygonDictionaryIndexCell>, true);
}
}

View File

@ -11,6 +11,11 @@
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
FinalCell::FinalCell(const std::vector<size_t> & polygon_ids_, const std::vector<Polygon> &, const Box &, bool is_last_covered_):
polygon_ids(polygon_ids_)
{
@ -62,7 +67,7 @@ const FinalCellWithSlabs * FinalCellWithSlabs::find(Coord, Coord) const
SlabsPolygonIndex::SlabsPolygonIndex(
const std::vector<Polygon> & polygons)
: log(&Logger::get("SlabsPolygonIndex")),
: log(&Poco::Logger::get("SlabsPolygonIndex")),
sorted_x(uniqueX(polygons))
{
indexBuild(polygons);
@ -100,7 +105,7 @@ void SlabsPolygonIndex::indexBuild(const std::vector<Polygon> & polygons)
}
/** Sorting edges of (left_point, right_point, polygon_id) in that order */
std::sort(all_edges.begin(), all_edges.end(), Edge::compare1);
std::sort(all_edges.begin(), all_edges.end(), Edge::compareByLeftPoint);
for (size_t i = 0; i != all_edges.size(); ++i)
all_edges[i].edge_id = i;
@ -112,7 +117,7 @@ void SlabsPolygonIndex::indexBuild(const std::vector<Polygon> & polygons)
/** Using custom comparator for fetching edges in right_point order, like in scanline */
auto cmp = [](const Edge & a, const Edge & b)
{
return Edge::compare2(a, b);
return Edge::compareByRightPoint(a, b);
};
std::set<Edge, decltype(cmp)> interesting_edges(cmp);
@ -155,9 +160,9 @@ void SlabsPolygonIndex::indexBuild(const std::vector<Polygon> & polygons)
size_t r = edge_right[i];
if (l == n || sorted_x[l] != all_edges[i].l.x() || sorted_x[r] != all_edges[i].r.x())
{
LOG_ERROR(log, "Error occured while building polygon index. Edge {} is [{}, {}] but found [{}, {}]. l = {}, r = {}",
i, all_edges[i].l.x(), all_edges[i].r.x(), sorted_x[l], sorted_x[r], l, r);
throw Poco::Exception("polygon index build error");
throw Exception(ErrorCodes::LOGICAL_ERROR,
"Error occured while building polygon index. Edge {} is [{}, {}] but found [{}, {}]. l = {}, r = {}",
i, all_edges[i].l.x(), all_edges[i].r.x(), sorted_x[l], sorted_x[r], l, r);
}
/** Adding [l, r) to the segment tree */
@ -221,7 +226,7 @@ SlabsPolygonIndex::Edge::Edge(
b = l.y() - k * l.x();
}
bool SlabsPolygonIndex::Edge::compare1(const Edge & a, const Edge & b)
bool SlabsPolygonIndex::Edge::compareByLeftPoint(const Edge & a, const Edge & b)
{
/** Comparing left point */
if (a.l.x() != b.l.x())
@ -238,7 +243,7 @@ bool SlabsPolygonIndex::Edge::compare1(const Edge & a, const Edge & b)
return a.polygon_id < b.polygon_id;
}
bool SlabsPolygonIndex::Edge::compare2(const Edge & a, const Edge & b)
bool SlabsPolygonIndex::Edge::compareByRightPoint(const Edge & a, const Edge & b)
{
/** Comparing right point */
if (a.r.x() != b.r.x())
@ -258,18 +263,6 @@ bool SlabsPolygonIndex::Edge::compare2(const Edge & a, const Edge & b)
return a.edge_id < b.edge_id;
}
namespace
{
inline void update_result(bool & found, size_t & id, const size_t & new_id)
{
if (!found || new_id < id)
{
found = true;
id = new_id;
}
}
}
bool SlabsPolygonIndex::find(const Point & point, size_t & id) const
{
/** Vertical line or nothing at all, no match here */
@ -315,7 +308,8 @@ bool SlabsPolygonIndex::find(const Point & point, size_t & id) const
{
if (i + 1 == intersections.size() || intersections[i] != intersections[i + 1])
{
update_result(found, id, intersections[i]);
found = true;
id = intersections[i];
break;
}
}

View File

@ -58,8 +58,8 @@ public:
Edge(const Point & l, const Point & r, size_t polygon_id, size_t edge_id);
static bool compare1(const Edge & a, const Edge & b);
static bool compare2(const Edge & a, const Edge & b);
static bool compareByLeftPoint(const Edge & a, const Edge & b);
static bool compareByRightPoint(const Edge & a, const Edge & b);
};
/** EdgeLine is optimized version of Edge. */

View File

@ -5,7 +5,7 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
TMP_DIR="/tmp"
declare -a SearchTypes=("POLYGON" "POLYGON_INDEX_EACH" "POLYGON_INDEX_CELL")
declare -a SearchTypes=("POLYGON" "POLYGON_SIMPLE" "POLYGON_INDEX_EACH" "POLYGON_INDEX_CELL")
tar -xf ${CURDIR}/01037_test_data_search.tar.gz -C ${CURDIR}

View File

@ -49,7 +49,7 @@ INSERT INTO test_01037.points VALUES (0.0, -2.0, 774, 'ffd');
"
declare -a SearchTypes=("POLYGON" "POLYGON_INDEX_EACH" "POLYGON_INDEX_CELL")
declare -a SearchTypes=("POLYGON" "POLYGON_SIMPLE" "POLYGON_INDEX_EACH" "POLYGON_INDEX_CELL")
for type in ${SearchTypes[@]};
do