mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-20 14:42:02 +00:00
better implementation
This commit is contained in:
parent
9e865d48ce
commit
17fa8076e3
@ -7,6 +7,7 @@
|
|||||||
#include <Common/LRUCache.h>
|
#include <Common/LRUCache.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
#include "Columns/IColumn.h"
|
#include "Columns/IColumn.h"
|
||||||
|
#include "Core/Field.h"
|
||||||
#include <base/unaligned.h>
|
#include <base/unaligned.h>
|
||||||
|
|
||||||
#include <Columns/ColumnString.h>
|
#include <Columns/ColumnString.h>
|
||||||
@ -15,8 +16,10 @@
|
|||||||
#include <Columns/ColumnLowCardinality.h>
|
#include <Columns/ColumnLowCardinality.h>
|
||||||
|
|
||||||
#include <Core/Defines.h>
|
#include <Core/Defines.h>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -39,19 +42,27 @@ struct HashMethodOneNumber
|
|||||||
using Base = columns_hashing_impl::HashMethodBase<Self, Value, Mapped, use_cache, need_offset>;
|
using Base = columns_hashing_impl::HashMethodBase<Self, Value, Mapped, use_cache, need_offset>;
|
||||||
|
|
||||||
const char * vec;
|
const char * vec;
|
||||||
bool column_is_const = false;
|
FieldType const_value;
|
||||||
|
std::function<FieldType(size_t row)> get_key_holder_impl;
|
||||||
|
|
||||||
/// If the keys of a fixed length then key_sizes contains their lengths, empty otherwise.
|
/// If the keys of a fixed length then key_sizes contains their lengths, empty otherwise.
|
||||||
HashMethodOneNumber(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
HashMethodOneNumber(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
||||||
{
|
{
|
||||||
vec = key_columns[0]->getRawData().data;
|
vec = key_columns[0]->getRawData().data;
|
||||||
column_is_const = isColumnConst(*key_columns[0]);
|
if (isColumnConst(*key_columns[0]))
|
||||||
|
{
|
||||||
|
const_value = unalignedLoad<FieldType>(vec);
|
||||||
|
get_key_holder_impl = [this](size_t /*row*/) { return const_value; };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
get_key_holder_impl = [this](size_t row) { return unalignedLoad<FieldType>(vec + row * sizeof(FieldType)); };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit HashMethodOneNumber(const IColumn * column)
|
explicit HashMethodOneNumber(const IColumn * column)
|
||||||
{
|
{
|
||||||
vec = column->getRawData().data;
|
vec = column->getRawData().data;
|
||||||
column_is_const = isColumnConst(*column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates context. Method is called once and result context is used in all threads.
|
/// Creates context. Method is called once and result context is used in all threads.
|
||||||
@ -69,11 +80,7 @@ struct HashMethodOneNumber
|
|||||||
using Base::getHash; /// (const Data & data, size_t row, Arena & pool) -> size_t
|
using Base::getHash; /// (const Data & data, size_t row, Arena & pool) -> size_t
|
||||||
|
|
||||||
/// Is used for default implementation in HashMethodBase.
|
/// Is used for default implementation in HashMethodBase.
|
||||||
FieldType getKeyHolder(size_t row, Arena &) const
|
FieldType getKeyHolder(size_t row, Arena &) const { return get_key_holder_impl(row); }
|
||||||
{
|
|
||||||
size_t pos = column_is_const ? 0 : row;
|
|
||||||
return unalignedLoad<FieldType>(vec + pos * sizeof(FieldType));
|
|
||||||
}
|
|
||||||
|
|
||||||
const FieldType * getKeyData() const { return reinterpret_cast<const FieldType *>(vec); }
|
const FieldType * getKeyData() const { return reinterpret_cast<const FieldType *>(vec); }
|
||||||
};
|
};
|
||||||
@ -89,27 +96,28 @@ struct HashMethodString
|
|||||||
|
|
||||||
const IColumn::Offset * offsets;
|
const IColumn::Offset * offsets;
|
||||||
const UInt8 * chars;
|
const UInt8 * chars;
|
||||||
bool column_is_const = false;
|
std::function<StringRef(size_t row)> get_key_holder_impl;
|
||||||
|
|
||||||
HashMethodString(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
HashMethodString(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
||||||
{
|
{
|
||||||
const IColumn * column = key_columns[0];
|
const IColumn * column = key_columns[0];
|
||||||
if (isColumnConst(*column))
|
bool column_is_const = isColumnConst(*column);
|
||||||
{
|
if (column_is_const)
|
||||||
column_is_const = true;
|
|
||||||
column = &assert_cast<const ColumnConst &>(*column).getDataColumn();
|
column = &assert_cast<const ColumnConst &>(*column).getDataColumn();
|
||||||
}
|
|
||||||
|
|
||||||
const ColumnString & column_string = assert_cast<const ColumnString &>(*column);
|
const ColumnString & column_string = assert_cast<const ColumnString &>(*column);
|
||||||
offsets = column_string.getOffsets().data();
|
offsets = column_string.getOffsets().data();
|
||||||
chars = column_string.getChars().data();
|
chars = column_string.getChars().data();
|
||||||
|
|
||||||
|
if (column_is_const)
|
||||||
|
get_key_holder_impl = [this](size_t /*row*/) { return StringRef(chars, offsets[0] - 1); };
|
||||||
|
else
|
||||||
|
get_key_holder_impl = [this](size_t row) { return StringRef(chars + offsets[row - 1], offsets[row] - offsets[row - 1] - 1); };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getKeyHolder(ssize_t row, [[maybe_unused]] Arena & pool) const
|
auto getKeyHolder(ssize_t row, [[maybe_unused]] Arena & pool) const
|
||||||
{
|
{
|
||||||
ssize_t pos = column_is_const ? 0 : row;
|
StringRef key = get_key_holder_impl(row);
|
||||||
StringRef key(chars + offsets[pos - 1], offsets[pos] - offsets[pos - 1] - 1);
|
|
||||||
|
|
||||||
if constexpr (place_string_to_arena)
|
if constexpr (place_string_to_arena)
|
||||||
{
|
{
|
||||||
return ArenaKeyHolder{key, pool};
|
return ArenaKeyHolder{key, pool};
|
||||||
@ -136,7 +144,7 @@ struct HashMethodFixedString
|
|||||||
|
|
||||||
size_t n;
|
size_t n;
|
||||||
const ColumnFixedString::Chars * chars;
|
const ColumnFixedString::Chars * chars;
|
||||||
bool column_is_const = false;
|
std::function<StringRef(size_t row)> get_key_holder_impl;
|
||||||
|
|
||||||
HashMethodFixedString(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
HashMethodFixedString(const ColumnRawPtrs & key_columns, const Sizes & /*key_sizes*/, const HashMethodContextPtr &)
|
||||||
{
|
{
|
||||||
@ -144,13 +152,15 @@ struct HashMethodFixedString
|
|||||||
const ColumnFixedString & column_string = assert_cast<const ColumnFixedString &>(column);
|
const ColumnFixedString & column_string = assert_cast<const ColumnFixedString &>(column);
|
||||||
n = column_string.getN();
|
n = column_string.getN();
|
||||||
chars = &column_string.getChars();
|
chars = &column_string.getChars();
|
||||||
column_is_const = isColumnConst(column);
|
if (isColumnConst(column))
|
||||||
|
get_key_holder_impl = [this](size_t /*row*/) { return StringRef(&(*chars)[0], n); };
|
||||||
|
else
|
||||||
|
get_key_holder_impl = [this](size_t row) { return StringRef(&(*chars)[row * n], n); };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getKeyHolder(size_t row, [[maybe_unused]] Arena & pool) const
|
auto getKeyHolder(size_t row, [[maybe_unused]] Arena & pool) const
|
||||||
{
|
{
|
||||||
size_t pos = column_is_const ? 0 : row;
|
StringRef key = get_key_holder_impl(row);
|
||||||
StringRef key(&(*chars)[pos * n], n);
|
|
||||||
|
|
||||||
if constexpr (place_string_to_arena)
|
if constexpr (place_string_to_arena)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user