Commit e0b0a12e authored by Nikita Malyavin's avatar Nikita Malyavin

optimize search in favor of erase for the "small hash table" case

parent d81b581b
...@@ -30,12 +30,15 @@ class Open_address_hash ...@@ -30,12 +30,15 @@ class Open_address_hash
public: public:
using Hash_value_type= typename Key_trait::Hash_value_type; using Hash_value_type= typename Key_trait::Hash_value_type;
Open_address_hash() void init()
{ {
first.set_mark(true); first.set(EMPTY, true);
first.set_ptr(EMPTY);
second= EMPTY; second= EMPTY;
} }
Open_address_hash()
{
init();
}
~Open_address_hash() ~Open_address_hash()
{ {
...@@ -179,11 +182,14 @@ class Open_address_hash ...@@ -179,11 +182,14 @@ class Open_address_hash
template <typename Func> template <typename Func>
Value find(const Key &key, const Func &elem_suits) const Value find(const Key &key, const Func &elem_suits) const
{ {
if (first.mark()) if (likely(first.mark()))
{ {
if (first.ptr() && elem_suits(first.ptr())) if (first.ptr())
return first.ptr(); {
if (!is_empty(second) && elem_suits(second)) if (elem_suits(first.ptr()))
return first.ptr();
}
else if (!is_empty(second) && elem_suits(second))
return second; return second;
return EMPTY; return EMPTY;
...@@ -205,7 +211,8 @@ class Open_address_hash ...@@ -205,7 +211,8 @@ class Open_address_hash
{ {
if (!is_empty(first.ptr()) && is_equal(first.ptr(), value)) if (!is_empty(first.ptr()) && is_equal(first.ptr(), value))
{ {
first.set_ptr(EMPTY); first.set_ptr(second);
second= EMPTY;
return true; return true;
} }
else if (second && is_equal(second, value)) else if (second && is_equal(second, value))
...@@ -223,6 +230,8 @@ class Open_address_hash ...@@ -223,6 +230,8 @@ class Open_address_hash
if (!erase_from_bucket(value)) if (!erase_from_bucket(value))
return false; return false;
_size--; _size--;
if (!_size)
init();
return true; return true;
} }
...@@ -323,6 +332,12 @@ class Open_address_hash ...@@ -323,6 +332,12 @@ class Open_address_hash
static constexpr uint MARK_SHIFT = 63; static constexpr uint MARK_SHIFT = 63;
static constexpr uintptr_t MARK_MASK = (uintptr_t)1 << MARK_SHIFT; static constexpr uintptr_t MARK_MASK = (uintptr_t)1 << MARK_SHIFT;
void set(Value ptr, bool mark)
{
uintptr_t mark_bit = static_cast<uintptr_t>(mark) << MARK_SHIFT;
p = reinterpret_cast<uintptr_t>(ptr) | mark_bit;
}
void set_ptr(Value ptr) void set_ptr(Value ptr)
{ {
p = reinterpret_cast<uintptr_t>(ptr) | (p & MARK_MASK); p = reinterpret_cast<uintptr_t>(ptr) | (p & MARK_MASK);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment