Miscellaneous [#CLICKHOUSE-2].

This commit is contained in:
Alexey Milovidov 2017-08-20 04:05:59 +03:00
parent ce3e4676fa
commit 7dc4d6f7b3

View File

@ -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;
};