|
@@ -304,7 +304,7 @@ private:
|
|
}
|
|
}
|
|
|
|
|
|
template<typename Finder>
|
|
template<typename Finder>
|
|
- Bucket* lookup_with_hash(unsigned hash, Finder finder, Bucket** usable_bucket_for_writing = nullptr) const
|
|
|
|
|
|
+ Bucket* lookup_with_hash(unsigned hash, Finder finder) const
|
|
{
|
|
{
|
|
if (is_empty())
|
|
if (is_empty())
|
|
return nullptr;
|
|
return nullptr;
|
|
@@ -312,10 +312,6 @@ private:
|
|
for (;;) {
|
|
for (;;) {
|
|
auto& bucket = m_buckets[hash % m_capacity];
|
|
auto& bucket = m_buckets[hash % m_capacity];
|
|
|
|
|
|
- if (usable_bucket_for_writing && !*usable_bucket_for_writing && !bucket.used) {
|
|
|
|
- *usable_bucket_for_writing = &bucket;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (bucket.used && finder(*bucket.slot()))
|
|
if (bucket.used && finder(*bucket.slot()))
|
|
return &bucket;
|
|
return &bucket;
|
|
|
|
|
|
@@ -333,25 +329,25 @@ private:
|
|
|
|
|
|
Bucket& lookup_for_writing(const T& value)
|
|
Bucket& lookup_for_writing(const T& value)
|
|
{
|
|
{
|
|
- auto hash = TraitsForT::hash(value);
|
|
|
|
- Bucket* usable_bucket_for_writing = nullptr;
|
|
|
|
- if (auto* bucket_for_reading = lookup_with_hash(
|
|
|
|
- hash,
|
|
|
|
- [&value](auto& entry) { return TraitsForT::equals(entry, value); },
|
|
|
|
- &usable_bucket_for_writing)) {
|
|
|
|
- return *const_cast<Bucket*>(bucket_for_reading);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (should_grow())
|
|
if (should_grow())
|
|
rehash(capacity() * 2);
|
|
rehash(capacity() * 2);
|
|
- else if (usable_bucket_for_writing)
|
|
|
|
- return *usable_bucket_for_writing;
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+ auto hash = TraitsForT::hash(value);
|
|
|
|
+ Bucket* first_empty_bucket = nullptr;
|
|
for (;;) {
|
|
for (;;) {
|
|
auto& bucket = m_buckets[hash % m_capacity];
|
|
auto& bucket = m_buckets[hash % m_capacity];
|
|
- if (!bucket.used)
|
|
|
|
|
|
+
|
|
|
|
+ if (bucket.used && TraitsForT::equals(*bucket.slot(), value))
|
|
return bucket;
|
|
return bucket;
|
|
|
|
+
|
|
|
|
+ if (!bucket.used) {
|
|
|
|
+ if (!first_empty_bucket)
|
|
|
|
+ first_empty_bucket = &bucket;
|
|
|
|
+
|
|
|
|
+ if (!bucket.deleted)
|
|
|
|
+ return *const_cast<Bucket*>(first_empty_bucket);
|
|
|
|
+ }
|
|
|
|
+
|
|
hash = double_hash(hash);
|
|
hash = double_hash(hash);
|
|
}
|
|
}
|
|
}
|
|
}
|