mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Merge branch 'master' of github.com:yandex/ClickHouse
This commit is contained in:
commit
8ed6d55104
@ -334,7 +334,7 @@ else()
|
||||
add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"")
|
||||
endif()
|
||||
if(WITH_OPTIM)
|
||||
if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
|
||||
if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/x86.c)
|
||||
endif()
|
||||
if(HAVE_SSE42_INTRIN)
|
||||
|
@ -46,6 +46,9 @@ ColumnPtr callPointInPolygonImplWithPool(const IColumn & x, const IColumn & y, P
|
||||
GeoUtils::normalizePolygon(polygon);
|
||||
auto ptr = std::make_unique<PointInPolygonImpl>(polygon);
|
||||
|
||||
/// To allocate memory.
|
||||
ptr->init();
|
||||
|
||||
ProfileEvents::increment(ProfileEvents::PolygonsAddedToPool);
|
||||
ProfileEvents::increment(ProfileEvents::PolygonsInPoolAllocatedBytes, ptr->getAllocatedBytes());
|
||||
|
||||
@ -261,13 +264,13 @@ template <typename Type>
|
||||
using PointInPolygonWithGrid = GeoUtils::PointInPolygonWithGrid<Type>;
|
||||
|
||||
template <>
|
||||
const char * FunctionPointInPolygon<PointInPolygonCrossing>::name = "pointInPolygon";
|
||||
const char * FunctionPointInPolygon<PointInPolygonCrossing>::name = "pointInPolygonCrossing";
|
||||
template <>
|
||||
const char * FunctionPointInPolygon<PointInPolygonWinding>::name = "pointInPolygonWinding";
|
||||
template <>
|
||||
const char * FunctionPointInPolygon<PointInPolygonFranklin>::name = "pointInPolygonFranklin";
|
||||
template <>
|
||||
const char * FunctionPointInPolygon<PointInPolygonWithGrid, true>::name = "pointInPolygonWithGrid";
|
||||
const char * FunctionPointInPolygon<PointInPolygonWithGrid, true>::name = "pointInPolygon";
|
||||
|
||||
|
||||
void registerFunctionsGeo(FunctionFactory & factory)
|
||||
|
@ -290,6 +290,8 @@ inline float roundWithMode(float x, RoundingMode mode)
|
||||
case RoundingMode::Floor: return floorf(x);
|
||||
case RoundingMode::Ceil: return ceilf(x);
|
||||
case RoundingMode::Trunc: return truncf(x);
|
||||
default:
|
||||
throw Exception("Logical error: unexpected 'mode' parameter passed to function roundWithMode", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,6 +303,8 @@ inline double roundWithMode(double x, RoundingMode mode)
|
||||
case RoundingMode::Floor: return floor(x);
|
||||
case RoundingMode::Ceil: return ceil(x);
|
||||
case RoundingMode::Trunc: return trunc(x);
|
||||
default:
|
||||
throw Exception("Logical error: unexpected 'mode' parameter passed to function roundWithMode", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,36 +47,38 @@ namespace GeoUtils
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
UInt64 getPolygonAllocatedSize(Polygon && polygon)
|
||||
UInt64 getPolygonAllocatedBytes(const Polygon & polygon)
|
||||
{
|
||||
UInt64 size = 0;
|
||||
|
||||
using RingType = typename std::decay<Polygon>::type::ring_type;
|
||||
using RingType = typename Polygon::ring_type;
|
||||
using ValueType = typename RingType::value_type;
|
||||
|
||||
auto addSizeOfRing = [& size](const RingType & ring) { size += sizeof(ring) + ring.capacity(); };
|
||||
auto sizeOfRing = [](const RingType & ring) { return sizeof(ring) + ring.capacity() * sizeof(ValueType); };
|
||||
|
||||
addSizeOfRing(polygon.outer());
|
||||
size += sizeOfRing(polygon.outer());
|
||||
|
||||
const auto & inners = polygon.inners();
|
||||
size += sizeof(inners) + inners.capacity();
|
||||
size += sizeof(inners) + inners.capacity() * sizeof(RingType);
|
||||
for (auto & inner : inners)
|
||||
addSizeOfRing(inner);
|
||||
size += sizeOfRing(inner);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename MultiPolygon>
|
||||
UInt64 getMultiPolygonAllocatedSize(MultiPolygon && multi_polygon)
|
||||
UInt64 getMultiPolygonAllocatedBytes(const MultiPolygon & multi_polygon)
|
||||
{
|
||||
UInt64 size = multi_polygon.capacity();
|
||||
using ValueType = typename MultiPolygon::value_type;
|
||||
UInt64 size = multi_polygon.capacity() * sizeof(ValueType);
|
||||
|
||||
for (const auto & polygon : multi_polygon)
|
||||
size += getPolygonAllocatedSize(polygon);
|
||||
size += getPolygonAllocatedBytes(polygon);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename CoordinateType = Float32, UInt16 gridHeight = 8, UInt16 gridWidth = 8>
|
||||
template <typename CoordinateType = Float32>
|
||||
class PointInPolygonWithGrid
|
||||
{
|
||||
public:
|
||||
@ -87,10 +89,12 @@ public:
|
||||
using Box = boost::geometry::model::box<Point>;
|
||||
using Segment = boost::geometry::model::segment<Point>;
|
||||
|
||||
explicit PointInPolygonWithGrid(const Polygon & polygon) : polygon(polygon) {}
|
||||
explicit PointInPolygonWithGrid(const Polygon & polygon, UInt16 grid_size = 8)
|
||||
: grid_size(std::max<UInt16>(1, grid_size)), polygon(polygon) {}
|
||||
|
||||
inline void init();
|
||||
void init();
|
||||
|
||||
/// True if bound box is empty.
|
||||
bool hasEmptyBound() const { return has_empty_bound; }
|
||||
|
||||
UInt64 getAllocatedBytes() const;
|
||||
@ -110,11 +114,12 @@ private:
|
||||
|
||||
struct HalfPlane
|
||||
{
|
||||
/// Line
|
||||
/// Line, a * x + b * y + c = 0. Vector (a, b) points inside half-plane.
|
||||
CoordinateType a;
|
||||
CoordinateType b;
|
||||
CoordinateType c;
|
||||
|
||||
/// Take left half-plane.
|
||||
void fill(const Point & from, const Point & to)
|
||||
{
|
||||
a = -(to.y() - from.y());
|
||||
@ -128,15 +133,17 @@ private:
|
||||
|
||||
struct Cell
|
||||
{
|
||||
static const int maxStoredHalfPlanes = 2;
|
||||
static const int max_stored_half_planes = 2;
|
||||
|
||||
HalfPlane half_planes[maxStoredHalfPlanes];
|
||||
HalfPlane half_planes[max_stored_half_planes];
|
||||
size_t index_of_inner_polygon;
|
||||
CellType type;
|
||||
};
|
||||
|
||||
const UInt16 grid_size;
|
||||
|
||||
Polygon polygon;
|
||||
std::array<Cell, gridHeight * gridWidth> cells;
|
||||
std::vector<Cell> cells;
|
||||
std::vector<MultiPolygon> polygons;
|
||||
|
||||
CoordinateType cell_width;
|
||||
@ -155,7 +162,7 @@ private:
|
||||
void calcGridAttributes(Box & box);
|
||||
|
||||
template <typename T>
|
||||
T ALWAYS_INLINE getCellIndex(T row, T col) const { return row * gridWidth + col; }
|
||||
T ALWAYS_INLINE getCellIndex(T row, T col) const { return row * grid_size + col; }
|
||||
|
||||
/// Complex case. Will check intersection directly.
|
||||
inline void addComplexPolygonCell(size_t index, const Box & box);
|
||||
@ -178,21 +185,23 @@ private:
|
||||
inline Distance distance(const Point & point, const Polygon & polygon);
|
||||
};
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
UInt64 PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::getAllocatedBytes() const
|
||||
template <typename CoordinateType>
|
||||
UInt64 PointInPolygonWithGrid<CoordinateType>::getAllocatedBytes() const
|
||||
{
|
||||
UInt64 size = sizeof(*this);
|
||||
|
||||
size += polygons.capacity();
|
||||
size += cells.capacity() * sizeof(Cell);
|
||||
size += polygons.capacity() * sizeof(MultiPolygon);
|
||||
size += getPolygonAllocatedBytes(polygon);
|
||||
|
||||
for (const auto & polygon : polygons)
|
||||
size += getMultiPolygonAllocatedSize(polygon);
|
||||
size += getPolygonAllocatedSize(polygon);
|
||||
size += getMultiPolygonAllocatedBytes(polygon);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::init()
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::init()
|
||||
{
|
||||
if (!was_grid_built)
|
||||
buildGrid();
|
||||
@ -200,17 +209,17 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::init()
|
||||
was_grid_built = true;
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::calcGridAttributes(
|
||||
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box)
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::calcGridAttributes(
|
||||
PointInPolygonWithGrid<CoordinateType>::Box & box)
|
||||
{
|
||||
boost::geometry::envelope(polygon, box);
|
||||
|
||||
const Point & min_corner = box.min_corner();
|
||||
const Point & max_corner = box.max_corner();
|
||||
|
||||
cell_width = (max_corner.x() - min_corner.x()) / gridWidth;
|
||||
cell_height = (max_corner.y() - min_corner.y()) / gridHeight;
|
||||
cell_width = (max_corner.x() - min_corner.x()) / grid_size;
|
||||
cell_height = (max_corner.y() - min_corner.y()) / grid_size;
|
||||
|
||||
if (cell_width == 0 || cell_height == 0)
|
||||
{
|
||||
@ -224,20 +233,25 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::calcGridAttr
|
||||
y_shift = -min_corner.y();
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::buildGrid()
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::buildGrid()
|
||||
{
|
||||
Box box;
|
||||
calcGridAttributes(box);
|
||||
|
||||
if (has_empty_bound)
|
||||
return;
|
||||
|
||||
cells.assign(grid_size * grid_size, {});
|
||||
|
||||
const Point & min_corner = box.min_corner();
|
||||
|
||||
for (size_t row = 0; row < gridHeight; ++row)
|
||||
for (size_t row = 0; row < grid_size; ++row)
|
||||
{
|
||||
CoordinateType y_min = min_corner.y() + row * cell_height;
|
||||
CoordinateType y_max = min_corner.y() + (row + 1) * cell_height;
|
||||
|
||||
for (size_t col = 0; col < gridWidth; ++col)
|
||||
for (size_t col = 0; col < grid_size; ++col)
|
||||
{
|
||||
CoordinateType x_min = min_corner.x() + col * cell_width;
|
||||
CoordinateType x_max = min_corner.x() + (col + 1) * cell_width;
|
||||
@ -263,19 +277,22 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::buildGrid()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
bool PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::contains(CoordinateType x, CoordinateType y)
|
||||
template <typename CoordinateType>
|
||||
bool PointInPolygonWithGrid<CoordinateType>::contains(CoordinateType x, CoordinateType y)
|
||||
{
|
||||
if (has_empty_bound)
|
||||
return false;
|
||||
|
||||
CoordinateType float_row = (y + y_shift) * y_scale;
|
||||
CoordinateType float_col = (x + x_shift) * x_scale;
|
||||
|
||||
if (float_row < 0 || float_row > gridHeight)
|
||||
if (float_row < 0 || float_row > grid_size)
|
||||
return false;
|
||||
if (float_col < 0 || float_col > gridWidth)
|
||||
if (float_col < 0 || float_col > grid_size)
|
||||
return false;
|
||||
|
||||
int row = std::min<int>(float_row, gridHeight - 1);
|
||||
int col = std::min<int>(float_col, gridWidth - 1);
|
||||
int row = std::min<int>(float_row, grid_size - 1);
|
||||
int col = std::min<int>(float_col, grid_size - 1);
|
||||
|
||||
int index = getCellIndex(row, col);
|
||||
const auto & cell = cells[index];
|
||||
@ -300,11 +317,11 @@ bool PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::contains(Coo
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
typename PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Distance
|
||||
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::distance(
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Point & point,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & polygon)
|
||||
template <typename CoordinateType>
|
||||
typename PointInPolygonWithGrid<CoordinateType>::Distance
|
||||
PointInPolygonWithGrid<CoordinateType>::distance(
|
||||
const PointInPolygonWithGrid<CoordinateType>::Point & point,
|
||||
const PointInPolygonWithGrid<CoordinateType>::Polygon & polygon)
|
||||
{
|
||||
const auto & outer = polygon.outer();
|
||||
Distance distance = 0;
|
||||
@ -317,11 +334,11 @@ PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::distance(
|
||||
return distance;
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
std::vector<typename PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::HalfPlane>
|
||||
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::findHalfPlanes(
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & intersection)
|
||||
template <typename CoordinateType>
|
||||
std::vector<typename PointInPolygonWithGrid<CoordinateType>::HalfPlane>
|
||||
PointInPolygonWithGrid<CoordinateType>::findHalfPlanes(
|
||||
const PointInPolygonWithGrid<CoordinateType>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType>::Polygon & intersection)
|
||||
{
|
||||
std::vector<HalfPlane> half_planes;
|
||||
Polygon bound;
|
||||
@ -344,9 +361,9 @@ PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::findHalfPlanes(
|
||||
return half_planes;
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addComplexPolygonCell(
|
||||
size_t index, const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box)
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::addComplexPolygonCell(
|
||||
size_t index, const PointInPolygonWithGrid<CoordinateType>::Box & box)
|
||||
{
|
||||
cells[index].type = CellType::complexPolygon;
|
||||
cells[index].index_of_inner_polygon = polygons.size();
|
||||
@ -369,9 +386,9 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addComplexPo
|
||||
polygons.push_back(intersection);
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
|
||||
size_t index, const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & empty_box)
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::addCell(
|
||||
size_t index, const PointInPolygonWithGrid<CoordinateType>::Box & empty_box)
|
||||
{
|
||||
const auto & min_corner = empty_box.min_corner();
|
||||
const auto & max_corner = empty_box.max_corner();
|
||||
@ -385,11 +402,11 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
|
||||
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::addCell(
|
||||
size_t index,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & intersection)
|
||||
const PointInPolygonWithGrid<CoordinateType>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType>::Polygon & intersection)
|
||||
{
|
||||
if (!intersection.inners().empty())
|
||||
addComplexPolygonCell(index, box);
|
||||
@ -413,12 +430,12 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
|
||||
addComplexPolygonCell(index, box);
|
||||
}
|
||||
|
||||
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth>
|
||||
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
|
||||
template <typename CoordinateType>
|
||||
void PointInPolygonWithGrid<CoordinateType>::addCell(
|
||||
size_t index,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & first,
|
||||
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & second)
|
||||
const PointInPolygonWithGrid<CoordinateType>::Box & box,
|
||||
const PointInPolygonWithGrid<CoordinateType>::Polygon & first,
|
||||
const PointInPolygonWithGrid<CoordinateType>::Polygon & second)
|
||||
{
|
||||
if (!first.inners().empty() || !second.inners().empty())
|
||||
addComplexPolygonCell(index, box);
|
||||
|
@ -380,10 +380,10 @@ void HTTPHandler::processQuery(
|
||||
std::unique_ptr<ReadBuffer> in_param = std::make_unique<ReadBufferFromString>(query_param);
|
||||
|
||||
std::unique_ptr<ReadBuffer> in_post_raw;
|
||||
/// A grubby workaround for CLICKHOUSE-3333 problem. This if should detect POST query with empty body.
|
||||
/// A grubby workaround for CLICKHOUSE-3333 problem. This condition should detect POST query with empty body.
|
||||
/// In that case Poco doesn't work properly and returns HTTPInputStream which just listen TCP connection.
|
||||
/// NOTE: if Poco are updated, this heuristic might not work properly.
|
||||
if (dynamic_cast<Poco::Net::HTTPInputStream *>(&istr) == nullptr)
|
||||
if (typeid_cast<Poco::Net::HTTPInputStream *>(&istr) == nullptr)
|
||||
in_post_raw = std::make_unique<ReadBufferFromIStream>(istr);
|
||||
else
|
||||
in_post_raw = std::make_unique<ReadBufferFromString>(String()); // will read empty body.
|
||||
|
@ -29,9 +29,8 @@ if (ENABLE_MYSQL)
|
||||
|
||||
if (MYSQL_INCLUDE_DIR AND (STATIC_MYSQLCLIENT_LIB OR MYSQLCLIENT_LIBRARIES))
|
||||
set (USE_MYSQL 1)
|
||||
set (MYSQLXX_LIBRARY mysqlxx)
|
||||
endif ()
|
||||
|
||||
set (MYSQLXX_LIBRARY mysqlxx)
|
||||
endif ()
|
||||
|
||||
if (USE_MYSQL)
|
||||
|
Loading…
Reference in New Issue
Block a user