aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp
diff options
context:
space:
mode:
authortender-bum <tender-bum@yandex-team.ru>2022-02-10 16:50:01 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:50:01 +0300
commit4aef354b224559d2b031487a10d4f5cc6e82e95a (patch)
tree5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/containers/flat_hash/lib/ut/table_ut.cpp
parentc78b06a63de7beec995c1007bc5332bdf3d75b69 (diff)
downloadydb-4aef354b224559d2b031487a10d4f5cc6e82e95a.tar.gz
Restoring authorship annotation for <tender-bum@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers/flat_hash/lib/ut/table_ut.cpp')
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/table_ut.cpp810
1 files changed, 405 insertions, 405 deletions
diff --git a/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp
index dda4ba3fd0..ea511e2c6a 100644
--- a/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp
+++ b/library/cpp/containers/flat_hash/lib/ut/table_ut.cpp
@@ -3,409 +3,409 @@
#include <library/cpp/containers/flat_hash/lib/probings.h>
#include <library/cpp/containers/flat_hash/lib/size_fitters.h>
#include <library/cpp/containers/flat_hash/lib/table.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/generic/algorithm.h>
-#include <util/random/random.h>
-#include <util/random/shuffle.h>
-
-using namespace NFlatHash;
-
-namespace {
- template <class T>
- struct TJustType {
- using type = T;
- };
-
- template <class... Ts>
- struct TTypePack {};
-
- template <class F, class... Ts>
- constexpr void ForEachType(F&& f, TTypePack<Ts...>) {
- ApplyToMany(std::forward<F>(f), TJustType<Ts>{}...);
- }
-
-/* Usage example:
- *
- * TForEachType<int, float, TString>::Apply([](auto t) {
- * using T = GET_TYPE(t);
- * });
- * So T would be:
- * int on #0 iteration
- * float on #1 iteration
- * TString on #2 iteration
- */
-#define GET_TYPE(ti) typename decltype(ti)::type
-
- constexpr size_t INIT_SIZE = 32;
- constexpr size_t BIG_INIT_SIZE = 128;
-
- template <class T>
- struct TSimpleKeyGetter {
- static constexpr T& Apply(T& t) { return t; }
- static constexpr const T& Apply(const T& t) { return t; }
- };
-
- template <class T,
- class KeyEqual = std::equal_to<T>,
- class ValueEqual = std::equal_to<T>,
- class KeyGetter = TSimpleKeyGetter<T>,
- class F,
- class... Containers>
- void ForEachTable(F f, TTypePack<Containers...> cs) {
- ForEachType([&](auto p) {
- using TProbing = GET_TYPE(p);
-
- ForEachType([&](auto sf) {
- using TSizeFitter = GET_TYPE(sf);
-
- ForEachType([&](auto t) {
- using TContainer = GET_TYPE(t);
- static_assert(std::is_same_v<typename TContainer::value_type, T>);
-
- using TTable = TTable<THash<T>,
- KeyEqual,
- TContainer,
- KeyGetter,
- TProbing,
- TSizeFitter,
- TSimpleExpander>;
-
- f(TJustType<TTable>{});
- }, cs);
- }, TTypePack<TAndSizeFitter, TModSizeFitter>{});
- }, TTypePack<TLinearProbing, TQuadraticProbing, TDenseProbing>{});
- }
-
- using TAtomContainers = TTypePack<TFlatContainer<int>,
- TDenseContainer<int, NSet::TStaticValueMarker<-1>>>;
- using TContainers = TTypePack<TFlatContainer<int>,
- TDenseContainer<int, NSet::TStaticValueMarker<-1>>>;
- using TRemovalContainers = TTypePack<TFlatContainer<int>,
- TRemovalDenseContainer<int, NSet::TStaticValueMarker<-2>,
- NSet::TStaticValueMarker<-1>>>;
-}
-
-Y_UNIT_TEST_SUITE(TCommonTableAtomsTest) {
- Y_UNIT_TEST(InitTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- UNIT_ASSERT(table.empty());
- UNIT_ASSERT_EQUAL(table.size(), 0);
- UNIT_ASSERT_EQUAL(table.bucket_count(), INIT_SIZE);
- UNIT_ASSERT_EQUAL(table.bucket_size(RandomNumber<size_t>(INIT_SIZE)), 0);
- }, TAtomContainers{});
- }
-
- Y_UNIT_TEST(IteratorTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- auto first = table.begin();
- auto last = table.end();
- UNIT_ASSERT_EQUAL(first, last);
- UNIT_ASSERT_EQUAL(std::distance(first, last), 0);
-
- auto cFirst = table.cbegin();
- auto cLast = table.cend();
- UNIT_ASSERT_EQUAL(cFirst, cLast);
- UNIT_ASSERT_EQUAL(std::distance(cFirst, cLast), 0);
- }, TAtomContainers{});
- }
-
- Y_UNIT_TEST(ContainsAndCountTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- for (int i = 0; i < 100; ++i) {
- UNIT_ASSERT_EQUAL(table.count(i), 0);
- UNIT_ASSERT(!table.contains(i));
- }
- }, TAtomContainers{});
- }
-
- Y_UNIT_TEST(FindTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- for (int i = 0; i < 100; ++i) {
- auto it = table.find(i);
- UNIT_ASSERT_EQUAL(it, table.end());
- }
- }, TAtomContainers{});
- }
-}
-
-Y_UNIT_TEST_SUITE(TCommonTableTest) {
- Y_UNIT_TEST(InsertTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- UNIT_ASSERT(table.empty());
- UNIT_ASSERT_EQUAL(table.size(), 0);
-
- int toInsert = RandomNumber<size_t>(100);
- UNIT_ASSERT_EQUAL(table.count(toInsert), 0);
- UNIT_ASSERT(!table.contains(toInsert));
-
- auto p = table.insert(toInsert);
- UNIT_ASSERT_EQUAL(p.first, table.begin());
- UNIT_ASSERT(p.second);
-
- UNIT_ASSERT(!table.empty());
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(toInsert), 1);
- UNIT_ASSERT(table.contains(toInsert));
-
- auto it = table.find(toInsert);
- UNIT_ASSERT_UNEQUAL(it, table.end());
- UNIT_ASSERT_EQUAL(it, table.begin());
- UNIT_ASSERT_EQUAL(*it, toInsert);
-
- auto p2 = table.insert(toInsert);
- UNIT_ASSERT_EQUAL(p.first, p2.first);
- UNIT_ASSERT(!p2.second);
-
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(toInsert), 1);
- UNIT_ASSERT(table.contains(toInsert));
- }, TContainers{});
- }
-
- Y_UNIT_TEST(ClearTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- TVector<int> toInsert(INIT_SIZE);
- Iota(toInsert.begin(), toInsert.end(), 0);
- ShuffleRange(toInsert);
- toInsert.resize(INIT_SIZE / 3);
-
- for (auto i : toInsert) {
- auto p = table.insert(i);
- UNIT_ASSERT_EQUAL(*p.first, i);
- UNIT_ASSERT(p.second);
- }
- UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
-
- for (auto i : toInsert) {
- UNIT_ASSERT(table.contains(i));
- UNIT_ASSERT_EQUAL(table.count(i), 1);
- }
-
- auto bc = table.bucket_count();
- table.clear();
- UNIT_ASSERT(table.empty());
- UNIT_ASSERT_EQUAL(table.bucket_count(), bc);
-
- for (auto i : toInsert) {
- UNIT_ASSERT(!table.contains(i));
- UNIT_ASSERT_EQUAL(table.count(i), 0);
- }
-
- table.insert(toInsert.front());
- UNIT_ASSERT(!table.empty());
- }, TContainers{});
- }
-
- Y_UNIT_TEST(CopyMoveTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- TVector<int> toInsert(INIT_SIZE);
- Iota(toInsert.begin(), toInsert.end(), 0);
- ShuffleRange(toInsert);
- toInsert.resize(INIT_SIZE / 3);
-
- for (auto i : toInsert) {
- auto p = table.insert(i);
- UNIT_ASSERT_EQUAL(*p.first, i);
- UNIT_ASSERT(p.second);
- }
- UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
-
- for (auto i : toInsert) {
- UNIT_ASSERT(table.contains(i));
- UNIT_ASSERT_EQUAL(table.count(i), 1);
- }
-
- // Copy construction test
- auto table2 = table;
- UNIT_ASSERT_EQUAL(table2.size(), table.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
- for (auto i : table) {
- UNIT_ASSERT(table2.contains(i));
- UNIT_ASSERT_EQUAL(table2.count(i), 1);
- }
-
- table2.clear();
- UNIT_ASSERT(table2.empty());
-
- // Copy assignment test
- table2 = table;
- UNIT_ASSERT_EQUAL(table2.size(), table.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
- for (auto i : table) {
- UNIT_ASSERT(table2.contains(i));
- UNIT_ASSERT_EQUAL(table2.count(i), 1);
- }
-
- // Move construction test
- auto table3 = std::move(table2);
- UNIT_ASSERT(table2.empty());
- UNIT_ASSERT(table2.bucket_count() > 0);
-
- UNIT_ASSERT_EQUAL(table3.size(), table.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table3.begin(), table3.end()), table.size());
- for (auto i : table) {
- UNIT_ASSERT(table3.contains(i));
- UNIT_ASSERT_EQUAL(table3.count(i), 1);
- }
-
- table2.insert(toInsert.front());
- UNIT_ASSERT(!table2.empty());
- UNIT_ASSERT_EQUAL(table2.size(), 1);
- UNIT_ASSERT_UNEQUAL(table2.bucket_count(), 0);
-
- // Move assignment test
- table2 = std::move(table3);
- UNIT_ASSERT(table3.empty());
- UNIT_ASSERT(table3.bucket_count() > 0);
-
- UNIT_ASSERT_EQUAL(table2.size(), table.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
- for (auto i : table) {
- UNIT_ASSERT(table2.contains(i));
- UNIT_ASSERT_EQUAL(table2.count(i), 1);
- }
-
- table3.insert(toInsert.front());
- UNIT_ASSERT(!table3.empty());
- UNIT_ASSERT_EQUAL(table3.size(), 1);
- UNIT_ASSERT_UNEQUAL(table3.bucket_count(), 0);
- }, TContainers{});
- }
-
- Y_UNIT_TEST(RehashTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- TVector<int> toInsert(INIT_SIZE);
- Iota(toInsert.begin(), toInsert.end(), 0);
- ShuffleRange(toInsert);
- toInsert.resize(INIT_SIZE / 3);
-
- for (auto i : toInsert) {
- table.insert(i);
- }
-
- auto bc = table.bucket_count();
- table.rehash(bc * 2);
- UNIT_ASSERT(bc * 2 <= table.bucket_count());
-
- UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
- UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
- for (auto i : toInsert) {
- UNIT_ASSERT(table.contains(i));
- UNIT_ASSERT_EQUAL(table.count(i), 1);
- }
-
- TVector<int> tmp(table.begin(), table.end());
- Sort(toInsert.begin(), toInsert.end());
- Sort(tmp.begin(), tmp.end());
-
- UNIT_ASSERT_VALUES_EQUAL(tmp, toInsert);
-
- table.rehash(0);
- UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
- UNIT_ASSERT(table.bucket_count() > table.size());
-
- table.clear();
- UNIT_ASSERT(table.empty());
- table.rehash(INIT_SIZE);
- UNIT_ASSERT(table.bucket_count() >= INIT_SIZE);
-
- table.rehash(0);
- UNIT_ASSERT(table.bucket_count() > 0);
- }, TContainers{});
- }
-
- Y_UNIT_TEST(EraseTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ INIT_SIZE };
-
- int value = RandomNumber<ui32>();
- table.insert(value);
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(value), 1);
-
- auto it = table.find(value);
- table.erase(it);
-
- UNIT_ASSERT_EQUAL(table.size(), 0);
- UNIT_ASSERT_EQUAL(table.count(value), 0);
-
- table.insert(value);
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(value), 1);
-
- table.erase(value);
-
- UNIT_ASSERT_EQUAL(table.size(), 0);
- UNIT_ASSERT_EQUAL(table.count(value), 0);
-
- table.insert(value);
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(value), 1);
-
- table.erase(table.find(value), table.end());
-
- UNIT_ASSERT_EQUAL(table.size(), 0);
- UNIT_ASSERT_EQUAL(table.count(value), 0);
-
- table.erase(value);
-
- UNIT_ASSERT_EQUAL(table.size(), 0);
- UNIT_ASSERT_EQUAL(table.count(value), 0);
- }, TRemovalContainers{});
- }
-
- Y_UNIT_TEST(EraseBigTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ BIG_INIT_SIZE };
-
- for (int i = 0; i < 1000; ++i) {
- for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) {
- table.emplace(j);
- }
- for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) {
- table.erase(j);
- }
- }
- UNIT_ASSERT(table.bucket_count() <= BIG_INIT_SIZE * 8);
- }, TRemovalContainers{});
- }
-
- Y_UNIT_TEST(ConstructWithSizeTest) {
- ForEachTable<int>([](auto t) {
- GET_TYPE(t) table{ 1000 };
- UNIT_ASSERT(table.bucket_count() >= 1000);
-
- int value = RandomNumber<ui32>();
- table.insert(value);
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(value), 1);
- UNIT_ASSERT(table.bucket_count() >= 1000);
-
- table.rehash(10);
- UNIT_ASSERT_EQUAL(table.size(), 1);
- UNIT_ASSERT_EQUAL(table.count(value), 1);
- UNIT_ASSERT(table.bucket_count() < 1000);
- UNIT_ASSERT(table.bucket_count() >= 10);
- }, TContainers{});
- }
-}
+
+#include <util/generic/algorithm.h>
+#include <util/random/random.h>
+#include <util/random/shuffle.h>
+
+using namespace NFlatHash;
+
+namespace {
+ template <class T>
+ struct TJustType {
+ using type = T;
+ };
+
+ template <class... Ts>
+ struct TTypePack {};
+
+ template <class F, class... Ts>
+ constexpr void ForEachType(F&& f, TTypePack<Ts...>) {
+ ApplyToMany(std::forward<F>(f), TJustType<Ts>{}...);
+ }
+
+/* Usage example:
+ *
+ * TForEachType<int, float, TString>::Apply([](auto t) {
+ * using T = GET_TYPE(t);
+ * });
+ * So T would be:
+ * int on #0 iteration
+ * float on #1 iteration
+ * TString on #2 iteration
+ */
+#define GET_TYPE(ti) typename decltype(ti)::type
+
+ constexpr size_t INIT_SIZE = 32;
+ constexpr size_t BIG_INIT_SIZE = 128;
+
+ template <class T>
+ struct TSimpleKeyGetter {
+ static constexpr T& Apply(T& t) { return t; }
+ static constexpr const T& Apply(const T& t) { return t; }
+ };
+
+ template <class T,
+ class KeyEqual = std::equal_to<T>,
+ class ValueEqual = std::equal_to<T>,
+ class KeyGetter = TSimpleKeyGetter<T>,
+ class F,
+ class... Containers>
+ void ForEachTable(F f, TTypePack<Containers...> cs) {
+ ForEachType([&](auto p) {
+ using TProbing = GET_TYPE(p);
+
+ ForEachType([&](auto sf) {
+ using TSizeFitter = GET_TYPE(sf);
+
+ ForEachType([&](auto t) {
+ using TContainer = GET_TYPE(t);
+ static_assert(std::is_same_v<typename TContainer::value_type, T>);
+
+ using TTable = TTable<THash<T>,
+ KeyEqual,
+ TContainer,
+ KeyGetter,
+ TProbing,
+ TSizeFitter,
+ TSimpleExpander>;
+
+ f(TJustType<TTable>{});
+ }, cs);
+ }, TTypePack<TAndSizeFitter, TModSizeFitter>{});
+ }, TTypePack<TLinearProbing, TQuadraticProbing, TDenseProbing>{});
+ }
+
+ using TAtomContainers = TTypePack<TFlatContainer<int>,
+ TDenseContainer<int, NSet::TStaticValueMarker<-1>>>;
+ using TContainers = TTypePack<TFlatContainer<int>,
+ TDenseContainer<int, NSet::TStaticValueMarker<-1>>>;
+ using TRemovalContainers = TTypePack<TFlatContainer<int>,
+ TRemovalDenseContainer<int, NSet::TStaticValueMarker<-2>,
+ NSet::TStaticValueMarker<-1>>>;
+}
+
+Y_UNIT_TEST_SUITE(TCommonTableAtomsTest) {
+ Y_UNIT_TEST(InitTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ UNIT_ASSERT(table.empty());
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+ UNIT_ASSERT_EQUAL(table.bucket_count(), INIT_SIZE);
+ UNIT_ASSERT_EQUAL(table.bucket_size(RandomNumber<size_t>(INIT_SIZE)), 0);
+ }, TAtomContainers{});
+ }
+
+ Y_UNIT_TEST(IteratorTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ auto first = table.begin();
+ auto last = table.end();
+ UNIT_ASSERT_EQUAL(first, last);
+ UNIT_ASSERT_EQUAL(std::distance(first, last), 0);
+
+ auto cFirst = table.cbegin();
+ auto cLast = table.cend();
+ UNIT_ASSERT_EQUAL(cFirst, cLast);
+ UNIT_ASSERT_EQUAL(std::distance(cFirst, cLast), 0);
+ }, TAtomContainers{});
+ }
+
+ Y_UNIT_TEST(ContainsAndCountTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ for (int i = 0; i < 100; ++i) {
+ UNIT_ASSERT_EQUAL(table.count(i), 0);
+ UNIT_ASSERT(!table.contains(i));
+ }
+ }, TAtomContainers{});
+ }
+
+ Y_UNIT_TEST(FindTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ for (int i = 0; i < 100; ++i) {
+ auto it = table.find(i);
+ UNIT_ASSERT_EQUAL(it, table.end());
+ }
+ }, TAtomContainers{});
+ }
+}
+
+Y_UNIT_TEST_SUITE(TCommonTableTest) {
+ Y_UNIT_TEST(InsertTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ UNIT_ASSERT(table.empty());
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+
+ int toInsert = RandomNumber<size_t>(100);
+ UNIT_ASSERT_EQUAL(table.count(toInsert), 0);
+ UNIT_ASSERT(!table.contains(toInsert));
+
+ auto p = table.insert(toInsert);
+ UNIT_ASSERT_EQUAL(p.first, table.begin());
+ UNIT_ASSERT(p.second);
+
+ UNIT_ASSERT(!table.empty());
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(toInsert), 1);
+ UNIT_ASSERT(table.contains(toInsert));
+
+ auto it = table.find(toInsert);
+ UNIT_ASSERT_UNEQUAL(it, table.end());
+ UNIT_ASSERT_EQUAL(it, table.begin());
+ UNIT_ASSERT_EQUAL(*it, toInsert);
+
+ auto p2 = table.insert(toInsert);
+ UNIT_ASSERT_EQUAL(p.first, p2.first);
+ UNIT_ASSERT(!p2.second);
+
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(toInsert), 1);
+ UNIT_ASSERT(table.contains(toInsert));
+ }, TContainers{});
+ }
+
+ Y_UNIT_TEST(ClearTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ TVector<int> toInsert(INIT_SIZE);
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ ShuffleRange(toInsert);
+ toInsert.resize(INIT_SIZE / 3);
+
+ for (auto i : toInsert) {
+ auto p = table.insert(i);
+ UNIT_ASSERT_EQUAL(*p.first, i);
+ UNIT_ASSERT(p.second);
+ }
+ UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
+
+ for (auto i : toInsert) {
+ UNIT_ASSERT(table.contains(i));
+ UNIT_ASSERT_EQUAL(table.count(i), 1);
+ }
+
+ auto bc = table.bucket_count();
+ table.clear();
+ UNIT_ASSERT(table.empty());
+ UNIT_ASSERT_EQUAL(table.bucket_count(), bc);
+
+ for (auto i : toInsert) {
+ UNIT_ASSERT(!table.contains(i));
+ UNIT_ASSERT_EQUAL(table.count(i), 0);
+ }
+
+ table.insert(toInsert.front());
+ UNIT_ASSERT(!table.empty());
+ }, TContainers{});
+ }
+
+ Y_UNIT_TEST(CopyMoveTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ TVector<int> toInsert(INIT_SIZE);
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ ShuffleRange(toInsert);
+ toInsert.resize(INIT_SIZE / 3);
+
+ for (auto i : toInsert) {
+ auto p = table.insert(i);
+ UNIT_ASSERT_EQUAL(*p.first, i);
+ UNIT_ASSERT(p.second);
+ }
+ UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
+
+ for (auto i : toInsert) {
+ UNIT_ASSERT(table.contains(i));
+ UNIT_ASSERT_EQUAL(table.count(i), 1);
+ }
+
+ // Copy construction test
+ auto table2 = table;
+ UNIT_ASSERT_EQUAL(table2.size(), table.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
+ for (auto i : table) {
+ UNIT_ASSERT(table2.contains(i));
+ UNIT_ASSERT_EQUAL(table2.count(i), 1);
+ }
+
+ table2.clear();
+ UNIT_ASSERT(table2.empty());
+
+ // Copy assignment test
+ table2 = table;
+ UNIT_ASSERT_EQUAL(table2.size(), table.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
+ for (auto i : table) {
+ UNIT_ASSERT(table2.contains(i));
+ UNIT_ASSERT_EQUAL(table2.count(i), 1);
+ }
+
+ // Move construction test
+ auto table3 = std::move(table2);
+ UNIT_ASSERT(table2.empty());
+ UNIT_ASSERT(table2.bucket_count() > 0);
+
+ UNIT_ASSERT_EQUAL(table3.size(), table.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table3.begin(), table3.end()), table.size());
+ for (auto i : table) {
+ UNIT_ASSERT(table3.contains(i));
+ UNIT_ASSERT_EQUAL(table3.count(i), 1);
+ }
+
+ table2.insert(toInsert.front());
+ UNIT_ASSERT(!table2.empty());
+ UNIT_ASSERT_EQUAL(table2.size(), 1);
+ UNIT_ASSERT_UNEQUAL(table2.bucket_count(), 0);
+
+ // Move assignment test
+ table2 = std::move(table3);
+ UNIT_ASSERT(table3.empty());
+ UNIT_ASSERT(table3.bucket_count() > 0);
+
+ UNIT_ASSERT_EQUAL(table2.size(), table.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table2.begin(), table2.end()), table.size());
+ for (auto i : table) {
+ UNIT_ASSERT(table2.contains(i));
+ UNIT_ASSERT_EQUAL(table2.count(i), 1);
+ }
+
+ table3.insert(toInsert.front());
+ UNIT_ASSERT(!table3.empty());
+ UNIT_ASSERT_EQUAL(table3.size(), 1);
+ UNIT_ASSERT_UNEQUAL(table3.bucket_count(), 0);
+ }, TContainers{});
+ }
+
+ Y_UNIT_TEST(RehashTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ TVector<int> toInsert(INIT_SIZE);
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ ShuffleRange(toInsert);
+ toInsert.resize(INIT_SIZE / 3);
+
+ for (auto i : toInsert) {
+ table.insert(i);
+ }
+
+ auto bc = table.bucket_count();
+ table.rehash(bc * 2);
+ UNIT_ASSERT(bc * 2 <= table.bucket_count());
+
+ UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
+ UNIT_ASSERT_EQUAL((size_t)std::distance(table.begin(), table.end()), toInsert.size());
+ for (auto i : toInsert) {
+ UNIT_ASSERT(table.contains(i));
+ UNIT_ASSERT_EQUAL(table.count(i), 1);
+ }
+
+ TVector<int> tmp(table.begin(), table.end());
+ Sort(toInsert.begin(), toInsert.end());
+ Sort(tmp.begin(), tmp.end());
+
+ UNIT_ASSERT_VALUES_EQUAL(tmp, toInsert);
+
+ table.rehash(0);
+ UNIT_ASSERT_EQUAL(table.size(), toInsert.size());
+ UNIT_ASSERT(table.bucket_count() > table.size());
+
+ table.clear();
+ UNIT_ASSERT(table.empty());
+ table.rehash(INIT_SIZE);
+ UNIT_ASSERT(table.bucket_count() >= INIT_SIZE);
+
+ table.rehash(0);
+ UNIT_ASSERT(table.bucket_count() > 0);
+ }, TContainers{});
+ }
+
+ Y_UNIT_TEST(EraseTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ INIT_SIZE };
+
+ int value = RandomNumber<ui32>();
+ table.insert(value);
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(value), 1);
+
+ auto it = table.find(value);
+ table.erase(it);
+
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+ UNIT_ASSERT_EQUAL(table.count(value), 0);
+
+ table.insert(value);
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(value), 1);
+
+ table.erase(value);
+
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+ UNIT_ASSERT_EQUAL(table.count(value), 0);
+
+ table.insert(value);
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(value), 1);
+
+ table.erase(table.find(value), table.end());
+
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+ UNIT_ASSERT_EQUAL(table.count(value), 0);
+
+ table.erase(value);
+
+ UNIT_ASSERT_EQUAL(table.size(), 0);
+ UNIT_ASSERT_EQUAL(table.count(value), 0);
+ }, TRemovalContainers{});
+ }
+
+ Y_UNIT_TEST(EraseBigTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ BIG_INIT_SIZE };
+
+ for (int i = 0; i < 1000; ++i) {
+ for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) {
+ table.emplace(j);
+ }
+ for (int j = 0; j < static_cast<int>(BIG_INIT_SIZE); ++j) {
+ table.erase(j);
+ }
+ }
+ UNIT_ASSERT(table.bucket_count() <= BIG_INIT_SIZE * 8);
+ }, TRemovalContainers{});
+ }
+
+ Y_UNIT_TEST(ConstructWithSizeTest) {
+ ForEachTable<int>([](auto t) {
+ GET_TYPE(t) table{ 1000 };
+ UNIT_ASSERT(table.bucket_count() >= 1000);
+
+ int value = RandomNumber<ui32>();
+ table.insert(value);
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(value), 1);
+ UNIT_ASSERT(table.bucket_count() >= 1000);
+
+ table.rehash(10);
+ UNIT_ASSERT_EQUAL(table.size(), 1);
+ UNIT_ASSERT_EQUAL(table.count(value), 1);
+ UNIT_ASSERT(table.bucket_count() < 1000);
+ UNIT_ASSERT(table.bucket_count() >= 10);
+ }, TContainers{});
+ }
+}