Merge branch 'master' of github.com:yandex/ClickHouse

This commit is contained in:
Alexey Milovidov 2017-09-25 15:07:48 +03:00
commit 8ed6d55104
6 changed files with 94 additions and 71 deletions

View File

@ -334,7 +334,7 @@ else()
add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"")
endif() endif()
if(WITH_OPTIM) 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) set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/x86.c)
endif() endif()
if(HAVE_SSE42_INTRIN) if(HAVE_SSE42_INTRIN)

View File

@ -46,6 +46,9 @@ ColumnPtr callPointInPolygonImplWithPool(const IColumn & x, const IColumn & y, P
GeoUtils::normalizePolygon(polygon); GeoUtils::normalizePolygon(polygon);
auto ptr = std::make_unique<PointInPolygonImpl>(polygon); auto ptr = std::make_unique<PointInPolygonImpl>(polygon);
/// To allocate memory.
ptr->init();
ProfileEvents::increment(ProfileEvents::PolygonsAddedToPool); ProfileEvents::increment(ProfileEvents::PolygonsAddedToPool);
ProfileEvents::increment(ProfileEvents::PolygonsInPoolAllocatedBytes, ptr->getAllocatedBytes()); ProfileEvents::increment(ProfileEvents::PolygonsInPoolAllocatedBytes, ptr->getAllocatedBytes());
@ -261,13 +264,13 @@ template <typename Type>
using PointInPolygonWithGrid = GeoUtils::PointInPolygonWithGrid<Type>; using PointInPolygonWithGrid = GeoUtils::PointInPolygonWithGrid<Type>;
template <> template <>
const char * FunctionPointInPolygon<PointInPolygonCrossing>::name = "pointInPolygon"; const char * FunctionPointInPolygon<PointInPolygonCrossing>::name = "pointInPolygonCrossing";
template <> template <>
const char * FunctionPointInPolygon<PointInPolygonWinding>::name = "pointInPolygonWinding"; const char * FunctionPointInPolygon<PointInPolygonWinding>::name = "pointInPolygonWinding";
template <> template <>
const char * FunctionPointInPolygon<PointInPolygonFranklin>::name = "pointInPolygonFranklin"; const char * FunctionPointInPolygon<PointInPolygonFranklin>::name = "pointInPolygonFranklin";
template <> template <>
const char * FunctionPointInPolygon<PointInPolygonWithGrid, true>::name = "pointInPolygonWithGrid"; const char * FunctionPointInPolygon<PointInPolygonWithGrid, true>::name = "pointInPolygon";
void registerFunctionsGeo(FunctionFactory & factory) void registerFunctionsGeo(FunctionFactory & factory)

View File

@ -290,6 +290,8 @@ inline float roundWithMode(float x, RoundingMode mode)
case RoundingMode::Floor: return floorf(x); case RoundingMode::Floor: return floorf(x);
case RoundingMode::Ceil: return ceilf(x); case RoundingMode::Ceil: return ceilf(x);
case RoundingMode::Trunc: return truncf(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::Floor: return floor(x);
case RoundingMode::Ceil: return ceil(x); case RoundingMode::Ceil: return ceil(x);
case RoundingMode::Trunc: return trunc(x); case RoundingMode::Trunc: return trunc(x);
default:
throw Exception("Logical error: unexpected 'mode' parameter passed to function roundWithMode", ErrorCodes::LOGICAL_ERROR);
} }
} }

View File

@ -47,36 +47,38 @@ namespace GeoUtils
template <typename Polygon> template <typename Polygon>
UInt64 getPolygonAllocatedSize(Polygon && polygon) UInt64 getPolygonAllocatedBytes(const Polygon & polygon)
{ {
UInt64 size = 0; 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(); const auto & inners = polygon.inners();
size += sizeof(inners) + inners.capacity(); size += sizeof(inners) + inners.capacity() * sizeof(RingType);
for (auto & inner : inners) for (auto & inner : inners)
addSizeOfRing(inner); size += sizeOfRing(inner);
return size; return size;
} }
template <typename MultiPolygon> 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) for (const auto & polygon : multi_polygon)
size += getPolygonAllocatedSize(polygon); size += getPolygonAllocatedBytes(polygon);
return size; return size;
} }
template <typename CoordinateType = Float32, UInt16 gridHeight = 8, UInt16 gridWidth = 8> template <typename CoordinateType = Float32>
class PointInPolygonWithGrid class PointInPolygonWithGrid
{ {
public: public:
@ -87,10 +89,12 @@ public:
using Box = boost::geometry::model::box<Point>; using Box = boost::geometry::model::box<Point>;
using Segment = boost::geometry::model::segment<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; } bool hasEmptyBound() const { return has_empty_bound; }
UInt64 getAllocatedBytes() const; UInt64 getAllocatedBytes() const;
@ -110,11 +114,12 @@ private:
struct HalfPlane struct HalfPlane
{ {
/// Line /// Line, a * x + b * y + c = 0. Vector (a, b) points inside half-plane.
CoordinateType a; CoordinateType a;
CoordinateType b; CoordinateType b;
CoordinateType c; CoordinateType c;
/// Take left half-plane.
void fill(const Point & from, const Point & to) void fill(const Point & from, const Point & to)
{ {
a = -(to.y() - from.y()); a = -(to.y() - from.y());
@ -128,15 +133,17 @@ private:
struct Cell 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; size_t index_of_inner_polygon;
CellType type; CellType type;
}; };
const UInt16 grid_size;
Polygon polygon; Polygon polygon;
std::array<Cell, gridHeight * gridWidth> cells; std::vector<Cell> cells;
std::vector<MultiPolygon> polygons; std::vector<MultiPolygon> polygons;
CoordinateType cell_width; CoordinateType cell_width;
@ -155,7 +162,7 @@ private:
void calcGridAttributes(Box & box); void calcGridAttributes(Box & box);
template <typename T> 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. /// Complex case. Will check intersection directly.
inline void addComplexPolygonCell(size_t index, const Box & box); inline void addComplexPolygonCell(size_t index, const Box & box);
@ -178,21 +185,23 @@ private:
inline Distance distance(const Point & point, const Polygon & polygon); inline Distance distance(const Point & point, const Polygon & polygon);
}; };
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
UInt64 PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::getAllocatedBytes() const UInt64 PointInPolygonWithGrid<CoordinateType>::getAllocatedBytes() const
{ {
UInt64 size = sizeof(*this); 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) for (const auto & polygon : polygons)
size += getMultiPolygonAllocatedSize(polygon); size += getMultiPolygonAllocatedBytes(polygon);
size += getPolygonAllocatedSize(polygon);
return size; return size;
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::init() void PointInPolygonWithGrid<CoordinateType>::init()
{ {
if (!was_grid_built) if (!was_grid_built)
buildGrid(); buildGrid();
@ -200,17 +209,17 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::init()
was_grid_built = true; was_grid_built = true;
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::calcGridAttributes( void PointInPolygonWithGrid<CoordinateType>::calcGridAttributes(
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box) PointInPolygonWithGrid<CoordinateType>::Box & box)
{ {
boost::geometry::envelope(polygon, box); boost::geometry::envelope(polygon, box);
const Point & min_corner = box.min_corner(); const Point & min_corner = box.min_corner();
const Point & max_corner = box.max_corner(); const Point & max_corner = box.max_corner();
cell_width = (max_corner.x() - min_corner.x()) / gridWidth; cell_width = (max_corner.x() - min_corner.x()) / grid_size;
cell_height = (max_corner.y() - min_corner.y()) / gridHeight; cell_height = (max_corner.y() - min_corner.y()) / grid_size;
if (cell_width == 0 || cell_height == 0) if (cell_width == 0 || cell_height == 0)
{ {
@ -224,20 +233,25 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::calcGridAttr
y_shift = -min_corner.y(); y_shift = -min_corner.y();
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::buildGrid() void PointInPolygonWithGrid<CoordinateType>::buildGrid()
{ {
Box box; Box box;
calcGridAttributes(box); calcGridAttributes(box);
if (has_empty_bound)
return;
cells.assign(grid_size * grid_size, {});
const Point & min_corner = box.min_corner(); 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_min = min_corner.y() + row * cell_height;
CoordinateType y_max = min_corner.y() + (row + 1) * 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_min = min_corner.x() + col * cell_width;
CoordinateType x_max = min_corner.x() + (col + 1) * 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> template <typename CoordinateType>
bool PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::contains(CoordinateType x, CoordinateType y) bool PointInPolygonWithGrid<CoordinateType>::contains(CoordinateType x, CoordinateType y)
{ {
if (has_empty_bound)
return false;
CoordinateType float_row = (y + y_shift) * y_scale; CoordinateType float_row = (y + y_shift) * y_scale;
CoordinateType float_col = (x + x_shift) * x_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; return false;
if (float_col < 0 || float_col > gridWidth) if (float_col < 0 || float_col > grid_size)
return false; return false;
int row = std::min<int>(float_row, gridHeight - 1); int row = std::min<int>(float_row, grid_size - 1);
int col = std::min<int>(float_col, gridWidth - 1); int col = std::min<int>(float_col, grid_size - 1);
int index = getCellIndex(row, col); int index = getCellIndex(row, col);
const auto & cell = cells[index]; const auto & cell = cells[index];
@ -300,11 +317,11 @@ bool PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::contains(Coo
} }
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
typename PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Distance typename PointInPolygonWithGrid<CoordinateType>::Distance
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::distance( PointInPolygonWithGrid<CoordinateType>::distance(
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Point & point, const PointInPolygonWithGrid<CoordinateType>::Point & point,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & polygon) const PointInPolygonWithGrid<CoordinateType>::Polygon & polygon)
{ {
const auto & outer = polygon.outer(); const auto & outer = polygon.outer();
Distance distance = 0; Distance distance = 0;
@ -317,11 +334,11 @@ PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::distance(
return distance; return distance;
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
std::vector<typename PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::HalfPlane> std::vector<typename PointInPolygonWithGrid<CoordinateType>::HalfPlane>
PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::findHalfPlanes( PointInPolygonWithGrid<CoordinateType>::findHalfPlanes(
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box, const PointInPolygonWithGrid<CoordinateType>::Box & box,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & intersection) const PointInPolygonWithGrid<CoordinateType>::Polygon & intersection)
{ {
std::vector<HalfPlane> half_planes; std::vector<HalfPlane> half_planes;
Polygon bound; Polygon bound;
@ -344,9 +361,9 @@ PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::findHalfPlanes(
return half_planes; return half_planes;
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addComplexPolygonCell( void PointInPolygonWithGrid<CoordinateType>::addComplexPolygonCell(
size_t index, const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box) size_t index, const PointInPolygonWithGrid<CoordinateType>::Box & box)
{ {
cells[index].type = CellType::complexPolygon; cells[index].type = CellType::complexPolygon;
cells[index].index_of_inner_polygon = polygons.size(); cells[index].index_of_inner_polygon = polygons.size();
@ -369,9 +386,9 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addComplexPo
polygons.push_back(intersection); polygons.push_back(intersection);
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell( void PointInPolygonWithGrid<CoordinateType>::addCell(
size_t index, const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & empty_box) size_t index, const PointInPolygonWithGrid<CoordinateType>::Box & empty_box)
{ {
const auto & min_corner = empty_box.min_corner(); const auto & min_corner = empty_box.min_corner();
const auto & max_corner = empty_box.max_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> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell( void PointInPolygonWithGrid<CoordinateType>::addCell(
size_t index, size_t index,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box, const PointInPolygonWithGrid<CoordinateType>::Box & box,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & intersection) const PointInPolygonWithGrid<CoordinateType>::Polygon & intersection)
{ {
if (!intersection.inners().empty()) if (!intersection.inners().empty())
addComplexPolygonCell(index, box); addComplexPolygonCell(index, box);
@ -413,12 +430,12 @@ void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell(
addComplexPolygonCell(index, box); addComplexPolygonCell(index, box);
} }
template <typename CoordinateType, UInt16 gridHeight, UInt16 gridWidth> template <typename CoordinateType>
void PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::addCell( void PointInPolygonWithGrid<CoordinateType>::addCell(
size_t index, size_t index,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Box & box, const PointInPolygonWithGrid<CoordinateType>::Box & box,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & first, const PointInPolygonWithGrid<CoordinateType>::Polygon & first,
const PointInPolygonWithGrid<CoordinateType, gridHeight, gridWidth>::Polygon & second) const PointInPolygonWithGrid<CoordinateType>::Polygon & second)
{ {
if (!first.inners().empty() || !second.inners().empty()) if (!first.inners().empty() || !second.inners().empty())
addComplexPolygonCell(index, box); addComplexPolygonCell(index, box);

View File

@ -380,10 +380,10 @@ void HTTPHandler::processQuery(
std::unique_ptr<ReadBuffer> in_param = std::make_unique<ReadBufferFromString>(query_param); std::unique_ptr<ReadBuffer> in_param = std::make_unique<ReadBufferFromString>(query_param);
std::unique_ptr<ReadBuffer> in_post_raw; 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. /// 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. /// 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); in_post_raw = std::make_unique<ReadBufferFromIStream>(istr);
else else
in_post_raw = std::make_unique<ReadBufferFromString>(String()); // will read empty body. in_post_raw = std::make_unique<ReadBufferFromString>(String()); // will read empty body.

View File

@ -29,9 +29,8 @@ if (ENABLE_MYSQL)
if (MYSQL_INCLUDE_DIR AND (STATIC_MYSQLCLIENT_LIB OR MYSQLCLIENT_LIBRARIES)) if (MYSQL_INCLUDE_DIR AND (STATIC_MYSQLCLIENT_LIB OR MYSQLCLIENT_LIBRARIES))
set (USE_MYSQL 1) set (USE_MYSQL 1)
set (MYSQLXX_LIBRARY mysqlxx)
endif () endif ()
set (MYSQLXX_LIBRARY mysqlxx)
endif () endif ()
if (USE_MYSQL) if (USE_MYSQL)