37# include <gtest/gtest.h>
46using namespace testing;
56 const size_t cap =
tbl.capacity();
57 for (
size_t i = 0; i < cap; ++i)
65 for (
size_t i = 0; i <
tbl.size(); ++i)
68 auto ptr =
tbl.search(i);
73 for (
size_t i = 0, n =
tbl.size(); i < n; ++i)
75 auto ptr =
tbl.search(i);
98 return r1.key == r2.key;
116 for (
size_t i = 0; i < 100; ++i)
127 for (
size_t i = 0, n =
tbl.size(); i < n; ++i)
129 auto ptr =
tbl.search(i);
144 auto *bucket =
decltype(
tbl)::key_to_bucket(ptr);
159 const int num_elements = 50;
160 for (
int i = 0; i < num_elements; ++i)
167 for (
int i = 0; i < 10; ++i)
175 <<
"Table size should not change after failed remove attempts";
178 for (
int i = 0; i < num_elements; ++i)
180 auto ptr =
tbl.search(i * 2);
182 <<
"Element " << i * 2 <<
" should still be in the table";
188 for (
int i = 0; i < num_elements; ++i)
190 auto ptr =
tbl.search(i * 2);
205 for (
int i = 0; i < 20; ++i)
217 for (
int i = 0; i < 20; ++i)
219 if (i == 10)
continue;
220 EXPECT_NE(
tbl.search(i),
nullptr) <<
"Element " << i <<
" should still exist";
230 for (
int i = 0; i < 20; ++i)
236 auto ptr =
tbl.search(10);
250 const int num_elements = 15;
251 for (
int i = 0; i < num_elements; ++i)
257 for (
int i = 0; i < num_elements; ++i)
258 EXPECT_NE(
tbl.search(i),
nullptr) <<
"Element " << i <<
" not found";
261 for (
int i = 0; i < num_elements; i += 2)
263 auto ptr =
tbl.search(i);
269 for (
int i = 1; i < num_elements; i += 2)
270 EXPECT_NE(
tbl.search(i),
nullptr) <<
"Element " << i <<
" not found after removals";
273 for (
int i = 0; i < num_elements; i += 2)
274 EXPECT_EQ(
tbl.search(i),
nullptr) <<
"Element " << i <<
" should be removed";
283 for (
int i = 0; i < 50; ++i)
298 <<
"Capacity changed after failed remove attempts";
304 for (
int i = 0; i < 50; ++i)
305 EXPECT_NE(
tbl.search(i * 2),
nullptr) <<
"Element " << i * 2 <<
" not found";
335 auto ptr =
tbl.insert(key);
357 catch (
const domain_error &)
359 FAIL() <<
"Remove threw for key " << key <<
" that was in oracle";
370 auto ptr =
tbl.search(key);
384 ASSERT_NE(
tbl.search(key),
nullptr) <<
"Final: key " << key <<
" missing";
391 const size_t target =
tbl.capacity() - 1;
394 for (
size_t i = 0; i < target; ++i)
396 auto ptr =
tbl.insert(
static_cast<int>(i));
397 ASSERT_NE(ptr,
nullptr) <<
"Insert failed at i=" << i;
403 for (
size_t i = 0; i < target; ++i)
407 vector<int>
keys(target);
413 for (
size_t i = 0; i < target; ++i)
426 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
430 const int num_elements = 50;
431 for (
int i = 0; i < num_elements; ++i)
433 auto ptr =
tbl.insert(i);
434 ASSERT_NE(ptr,
nullptr) <<
"Insert failed at i=" << i;
440 for (
int i = 0; i < num_elements; ++i)
442 auto ptr =
tbl.search(i);
443 ASSERT_NE(ptr,
nullptr) <<
"Element " << i <<
" not found";
448 for (
int i = 0; i < num_elements; ++i)
462 const int cycles = 100;
498 auto ptr =
tbl.insert(key);
499 if (
oracle.count(key) == 0 && ptr !=
nullptr)
507 ASSERT_NE(
tbl.search(key),
nullptr) <<
"Key " << key <<
" lost after resize";
523 for (
int i = 0; i <
num_ops; ++i)
530 auto ptr =
tbl.insert(key);
543 catch (
const domain_error &)
545 FAIL() <<
"Remove threw for key " << key <<
" that was in oracle";
551 auto ptr =
tbl.search(key);
575 auto ptr =
tbl.insert(key);
584 auto ptr =
tbl.search(key);
585 ASSERT_NE(ptr,
nullptr) <<
"Key " << key <<
" lost during resize";
601template <
typename HashTable>
605 for (
size_t i = 0; i <
tbl.capacity(); ++i)
607 switch (
tbl.table[i].status)
609 case HashTable::EMPTY: ++stats.
empty;
break;
610 case HashTable::BUSY: ++stats.
busy;
break;
611 case HashTable::DELETED: ++stats.
deleted;
break;
621 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
626 for (
int i = 0; i < 5; ++i)
638 EXPECT_EQ(
after.deleted, 0) <<
"Last element should become EMPTY, not DELETED";
642 for (
int i = 0; i < 4; ++i)
643 EXPECT_NE(
tbl.search(i),
nullptr) <<
"Element " << i <<
" should still exist";
652 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
656 for (
int i = 0; i < 5; ++i)
686 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
690 for (
int i = 0; i < 5; ++i)
698 EXPECT_EQ(stats.deleted, 1) <<
"Middle element should stay DELETED";
701 for (
int i = 0; i < 5; ++i)
716 const int cycles = 50;
717 const int elements = 30;
722 for (
int i = 0; i < elements; ++i)
726 for (
int i = 0; i < elements; ++i)
733 EXPECT_EQ(stats.deleted, 0) <<
"Should have no DELETED after complete removal";
746 return static_cast<size_t>(
k + 15);
752 for (
int i = 0; i < 5; ++i)
758 for (
int i = 4; i >= 0; --i)
764 EXPECT_EQ(stats.deleted, 0) <<
"Wrap-around cleanup should leave no DELETED";
780 for (
int i = 0; i <
num_ops; ++i)
787 auto ptr =
tbl.insert(key);
788 if (ptr)
oracle.insert(key);
790 else if (
oracle.count(key))
803 <<
"DELETED ratio should be low with cleanup. Got "
804 << stats.deleted <<
"/" <<
tbl.capacity();
819 for (
int i = 0; i < 50; ++i)
828 for (
int i = 0; i < 50; ++i)
843 for (
int i = 0; i < 50; ++i)
855 for (
int i = 0; i < 50; ++i)
862 for (
int i = 0; i < 50; ++i)
872 for (
int i = 0; i < 50; ++i)
881 for (
int i = 0; i < 50; ++i)
893 for (
int i = 0; i < 50; ++i)
900 for (
int i = 0; i < 50; ++i)
906 for (
int i = 0; i < 50; ++i)
916 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
920 for (
int i = 0; i < 5; ++i)
953 auto ptr =
tbl.search_or_insert(42);
964 auto ptr =
tbl.search_or_insert(42);
974 auto [ptr,
existed] =
tbl.contains_or_insert(42);
986 auto [ptr,
existed] =
tbl.contains_or_insert(42);
1002 for (
int i = 0; i < 50; ++i)
1009 for (
int i = 0; i < 50; i += 2)
1023 EXPECT_EQ(
after.deleted, 0) <<
"Rehash should eliminate all DELETED";
1035 for (
int i = 0; i < 30; ++i)
1044 for (
int i = 0; i < 30; ++i)
1052 for (
int i = 0; i < 30; ++i)
1059 for (
int i = 0; i < 30; ++i)
1101 auto first =
tbl.insert(42);
1104 auto second =
tbl.insert(42);
1105 EXPECT_EQ(second,
nullptr) <<
"Duplicate insert should return nullptr";
1131 int& ref =
tbl.find(42);
1147 for (
int i = 0; i < 50; ++i)
1154 for (
auto it =
tbl.get_it(); it.has_curr(); it.next())
1155 visited.insert(it.get_curr());
1164 auto it =
tbl.get_it();
1173 auto it =
tbl.get_it();
1185 for (
int i = 0; i < 10; ++i)
1189 auto it =
tbl.get_it();
1190 while (it.has_curr())
1202 auto bad_hash = [](
const int &) ->
size_t {
return 0; };
1206 for (
int i = 0; i < 10; ++i)
1214 auto stats =
tbl.stats();
1218 EXPECT_EQ(stats.num_busy + stats.num_deleted + stats.num_empty,
tbl.capacity());
1228 for (
int i = 0; i < 10; ++i)
1232 tbl.for_each([&
sum](
int x) {
sum += x; });
1240 for (
int i = 0; i < 10; ++i)
1250 for (
int i = 0; i < 10; ++i)
1260 for (
int i = 0; i < 10; ++i)
1263 auto evens =
tbl.filter([](
int x) {
return x % 2 == 0; });
Open addressing hash table with linear probing collision resolution.
Key * search(const Key &key) const noexcept
Finds the key and returns the associated record if key is find inside the table; otherwise,...
constexpr size_t size() const noexcept
Returns the number of entries in the table.
Key * insert(const Key &key)
Inserts a key into the hash table (copy version).
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
MapOLhash< int, Foo > tbl
Main namespace for Aleph-w library functions.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
void iota(C &container, typename C::Item_Type start)
Fill all elements of a container with unit-step sequential values.
size_t dft_hash_fct(const Key &key) noexcept
Primary default hash: best speed/quality trade-off.
auto shuffle(const C< T > &c)
Randomly shuffle a sequence.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
size_t my_hash(const MyRecord &r) noexcept
BucketStats count_bucket_states(const HashTable &tbl)
bool operator()(const MyRecord &r1, const MyRecord &r2) const noexcept
bool operator==(const MyRecord &r) const noexcept
MyRecord(size_t k, const string &v)
Open addressing hash table with linear probing.