mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-23 02:00:49 +00:00
Little better [#CLICKHOUSE-2].
This commit is contained in:
parent
6b075fdcbe
commit
3c33f1841f
@ -38,6 +38,8 @@ size_t countBytesInFilter(const IColumn::Filter & filt)
|
||||
| (static_cast<UInt64>(_mm_movemask_epi8(_mm_cmpgt_epi8(
|
||||
_mm_loadu_si128(reinterpret_cast<const __m128i *>(pos + 48)),
|
||||
zero16))) << 48));
|
||||
|
||||
/// TODO Add duff device for tail?
|
||||
#endif
|
||||
|
||||
for (; pos < end; ++pos)
|
||||
@ -47,6 +49,44 @@ size_t countBytesInFilter(const IColumn::Filter & filt)
|
||||
}
|
||||
|
||||
|
||||
/** clang 4 generates better code than gcc 6.
|
||||
* And both gcc and clang could not vectorize trivial loop by bytes automatically.
|
||||
*/
|
||||
bool memoryIsZero(const void * data, size_t size)
|
||||
{
|
||||
const Int8 * pos = reinterpret_cast<const Int8 *>(data);
|
||||
const Int8 * end = pos + size;
|
||||
|
||||
#if __SSE2__
|
||||
const __m128 zero16 = _mm_setzero_ps();
|
||||
const Int8 * end64 = pos + size / 64 * 64;
|
||||
|
||||
for (; pos < end64; pos += 64)
|
||||
if (_mm_movemask_ps(_mm_cmpneq_ps(
|
||||
_mm_loadu_ps(reinterpret_cast<const float *>(pos)),
|
||||
zero16))
|
||||
| _mm_movemask_ps(_mm_cmpneq_ps(
|
||||
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 16)),
|
||||
zero16))
|
||||
| _mm_movemask_ps(_mm_cmpneq_ps(
|
||||
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 32)),
|
||||
zero16))
|
||||
| _mm_movemask_ps(_mm_cmpneq_ps(
|
||||
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 48)),
|
||||
zero16)))
|
||||
return false;
|
||||
|
||||
/// TODO Add duff device for tail?
|
||||
#endif
|
||||
|
||||
for (; pos < end; ++pos)
|
||||
if (*pos)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
|
||||
|
@ -11,6 +11,9 @@ namespace DB
|
||||
/// Counts how many bytes of `filt` are greater than zero.
|
||||
size_t countBytesInFilter(const IColumn::Filter & filt);
|
||||
|
||||
/// Returns true, if the memory contains only zeros.
|
||||
bool memoryIsZero(const void * data, size_t size);
|
||||
|
||||
|
||||
/// The general implementation of `filter` function for ColumnArray and ColumnString.
|
||||
template <typename T>
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <DataStreams/NullableAdapterBlockInputStream.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <Columns/ColumnsCommon.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataStreams/isConvertableTypes.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -51,7 +53,7 @@ Block NullableAdapterBlockInputStream::readImpl()
|
||||
const auto & nullable_type = static_cast<const DataTypeNullable &>(*elem.type);
|
||||
|
||||
const auto & null_map = nullable_col.getNullMap();
|
||||
bool has_nulls = std::any_of(null_map.begin(), null_map.end(), [](UInt8 val){ return val == 1; });
|
||||
bool has_nulls = !memoryIsZero(null_map.data(), null_map.size());
|
||||
|
||||
if (has_nulls)
|
||||
throw Exception{"Cannot insert NULL value into non-nullable column",
|
||||
|
Loading…
Reference in New Issue
Block a user