void DistinctBlockInputStream::buildFilter( Method & method, const ConstColumnPlainPtrs & columns, IColumn::Filter & filter, size_t rows, SetVariants & variants) const { typename Method::State state; state.init(columns); for (size_t i = 0; i < rows; ++i) { /// Make a key. typename Method::Key key = state.getKey(columns, columns.size(), i, key_sizes); typename Method::Data::iterator it = method.data.find(key); bool inserted; method.data.emplace(key, it, inserted); if (inserted) method.onNewKey(*it, columns.size(), i, variants.string_pool); /// Emit the record if there is no such key in the current set yet. /// Skip it otherwise. filter[i] = inserted; } }
void NO_INLINE Set::executeArrayImpl( Method & method, const ConstColumnPlainPtrs & key_columns, const ColumnArray::Offsets_t & offsets, ColumnUInt8::Container_t & vec_res, bool negative, size_t rows) const { typename Method::State state; state.init(key_columns); size_t keys_size = key_columns.size(); size_t prev_offset = 0; /// Для всех строчек for (size_t i = 0; i < rows; ++i) { UInt8 res = 0; /// Для всех элементов for (size_t j = prev_offset; j < offsets[i]; ++j) { /// Строим ключ typename Method::Key key = state.getKey(key_columns, keys_size, j, key_sizes); res |= negative ^ (method.data.end() != method.data.find(key)); if (res) break; } vec_res[i] = res; prev_offset = offsets[i]; } }
bool DistinctSortedBlockInputStream::buildFilter( Method & method, const ColumnRawPtrs & columns, const ColumnRawPtrs & clearing_hint_columns, IColumn::Filter & filter, size_t rows, ClearableSetVariants & variants) const { typename Method::State state; state.init(columns); /// Compare last row of previous block and first row of current block, /// If rows not equal, we can clear HashSet, /// If clearing_hint_columns is empty, we CAN'T clear HashSet. if (!clearing_hint_columns.empty() && !prev_block.clearing_hint_columns.empty() && !rowsEqual(clearing_hint_columns, 0, prev_block.clearing_hint_columns, prev_block.block.rows() - 1)) { method.data.clear(); } bool has_new_data = false; for (size_t i = 0; i < rows; ++i) { /// Compare i-th row and i-1-th row, /// If rows are not equal, we can clear HashSet, /// If clearing_hint_columns is empty, we CAN'T clear HashSet. if (i > 0 && !clearing_hint_columns.empty() && !rowsEqual(clearing_hint_columns, i, clearing_hint_columns, i - 1)) method.data.clear(); /// Make a key. typename Method::Key key = state.getKey(columns, columns.size(), i, key_sizes); typename Method::Data::iterator it = method.data.find(key); bool inserted; method.data.emplace(key, it, inserted); if (inserted) { method.onNewKey(*it, columns.size(), variants.string_pool); has_new_data = true; } /// Emit the record if there is no such key in the current set yet. /// Skip it otherwise. filter[i] = inserted; } return has_new_data; }
void NO_INLINE Set::executeImpl( Method & method, const ConstColumnPlainPtrs & key_columns, ColumnUInt8::Container_t & vec_res, bool negative, size_t rows) const { typename Method::State state; state.init(key_columns); size_t keys_size = key_columns.size(); /// NOTE Не используется оптимизация для подряд идущих одинаковых значений. /// Для всех строчек for (size_t i = 0; i < rows; ++i) { /// Строим ключ typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes); vec_res[i] = negative ^ (method.data.end() != method.data.find(key)); } }
void NO_INLINE Set::insertFromBlockImpl( Method & method, const ConstColumnPlainPtrs & key_columns, size_t rows, SetVariants & variants) { typename Method::State state; state.init(key_columns); size_t keys_size = key_columns.size(); /// Для всех строчек for (size_t i = 0; i < rows; ++i) { /// Строим ключ typename Method::Key key = state.getKey(key_columns, keys_size, i, key_sizes); typename Method::Data::iterator it = method.data.find(key); bool inserted; method.data.emplace(key, it, inserted); if (inserted) method.onNewKey(*it, keys_size, i, variants.string_pool); } }