mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Miscellaneous [#CLICKHOUSE-2].
This commit is contained in:
parent
ce3e4676fa
commit
7dc4d6f7b3
@ -293,6 +293,30 @@ protected:
|
||||
return place_value;
|
||||
}
|
||||
|
||||
|
||||
template <size_t N>
|
||||
size_t ALWAYS_INLINE findCellUnrolled(const Key & x, size_t hash_value, size_t place_value) const
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
size_t places[N];
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
places[i] = place_value;
|
||||
place_value = grower.next(place_value);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
const Cell & cell = buf[places[i]];
|
||||
|
||||
if (cell.isZero(*this) || cell.keyEquals(x, hash_value))
|
||||
return places[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Find an empty cell, starting with the specified position and further along the collision resolution chain.
|
||||
size_t ALWAYS_INLINE findEmptyCell(const Key & x, size_t hash_value, size_t place_value) const
|
||||
{
|
||||
@ -422,6 +446,50 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
template <typename Derived, bool is_const>
|
||||
class iterator_base
|
||||
{
|
||||
using Container = typename std::conditional<is_const, const Self, Self>::type;
|
||||
using cell_type = typename std::conditional<is_const, const Cell, Cell>::type;
|
||||
|
||||
Container * container;
|
||||
cell_type * ptr;
|
||||
|
||||
friend class HashTable;
|
||||
|
||||
public:
|
||||
iterator_base() {}
|
||||
iterator_base(Container * container_, cell_type * ptr_) : container(container_), ptr(ptr_) {}
|
||||
|
||||
bool operator== (const iterator_base & rhs) const { return ptr == rhs.ptr; }
|
||||
bool operator!= (const iterator_base & rhs) const { return ptr != rhs.ptr; }
|
||||
|
||||
Derived & operator++()
|
||||
{
|
||||
if (unlikely(ptr->isZero(*container)))
|
||||
ptr = container->buf;
|
||||
else
|
||||
++ptr;
|
||||
|
||||
while (ptr < container->buf + container->grower.bufSize() && ptr->isZero(*container))
|
||||
++ptr;
|
||||
|
||||
return static_cast<Derived &>(*this);
|
||||
}
|
||||
|
||||
auto & operator* () const { return ptr->getValue(); }
|
||||
auto operator->() const { return &ptr->getValue(); }
|
||||
|
||||
auto getPtr() const { return ptr; }
|
||||
size_t getHash() const { return ptr->getHash(*container); }
|
||||
|
||||
size_t getCollisionChainLength() const
|
||||
{
|
||||
return container->grower.place((ptr - container->buf) - container->grower.place(getHash()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
using key_type = Key;
|
||||
using value_type = typename Cell::value_type;
|
||||
@ -499,74 +567,17 @@ public:
|
||||
bool is_initialized = false;
|
||||
};
|
||||
|
||||
class iterator
|
||||
|
||||
class iterator : public iterator_base<iterator, false>
|
||||
{
|
||||
Self * container;
|
||||
Cell * ptr;
|
||||
|
||||
friend class HashTable;
|
||||
|
||||
public:
|
||||
iterator() {}
|
||||
iterator(Self * container_, Cell * ptr_) : container(container_), ptr(ptr_) {}
|
||||
|
||||
bool operator== (const iterator & rhs) const { return ptr == rhs.ptr; }
|
||||
bool operator!= (const iterator & rhs) const { return ptr != rhs.ptr; }
|
||||
|
||||
iterator & operator++()
|
||||
{
|
||||
if (unlikely(ptr->isZero(*container)))
|
||||
ptr = container->buf;
|
||||
else
|
||||
++ptr;
|
||||
|
||||
while (ptr < container->buf + container->grower.bufSize() && ptr->isZero(*container))
|
||||
++ptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type & operator* () const { return ptr->getValue(); }
|
||||
value_type * operator->() const { return &ptr->getValue(); }
|
||||
|
||||
Cell * getPtr() const { return ptr; }
|
||||
size_t getHash() const { return ptr->getHash(*container); }
|
||||
using iterator_base<iterator, false>::iterator_base;
|
||||
};
|
||||
|
||||
|
||||
class const_iterator
|
||||
class const_iterator : public iterator_base<const_iterator, true>
|
||||
{
|
||||
const Self * container;
|
||||
const Cell * ptr;
|
||||
|
||||
friend class HashTable;
|
||||
|
||||
public:
|
||||
const_iterator() {}
|
||||
const_iterator(const Self * container_, const Cell * ptr_) : container(container_), ptr(ptr_) {}
|
||||
const_iterator(const iterator & rhs) : container(rhs.container), ptr(rhs.ptr) {}
|
||||
|
||||
bool operator== (const const_iterator & rhs) const { return ptr == rhs.ptr; }
|
||||
bool operator!= (const const_iterator & rhs) const { return ptr != rhs.ptr; }
|
||||
|
||||
const_iterator & operator++()
|
||||
{
|
||||
if (unlikely(ptr->isZero(*container)))
|
||||
ptr = container->buf;
|
||||
else
|
||||
++ptr;
|
||||
|
||||
while (ptr < container->buf + container->grower.bufSize() && ptr->isZero(*container))
|
||||
++ptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const value_type & operator* () const { return ptr->getValue(); }
|
||||
const value_type * operator->() const { return &ptr->getValue(); }
|
||||
|
||||
const Cell * getPtr() const { return ptr; }
|
||||
size_t getHash() const { return ptr->getHash(*container); }
|
||||
using iterator_base<const_iterator, true>::iterator_base;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user