aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/flat_hash/lib/ut
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
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')
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp816
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp164
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp62
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp98
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/table_ut.cpp810
-rw-r--r--library/cpp/containers/flat_hash/lib/ut/ya.make32
6 files changed, 991 insertions, 991 deletions
diff --git a/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp
index 9d39a43f90..b17b30fa80 100644
--- a/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp
+++ b/library/cpp/containers/flat_hash/lib/ut/containers_ut.cpp
@@ -1,410 +1,410 @@
#include <library/cpp/containers/flat_hash/lib/containers.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 {
- constexpr size_t INIT_SIZE = 128;
-
- struct TDummy {
- static size_t Count;
-
- TDummy() { ++Count; }
- TDummy(const TDummy&) { ++Count; }
- ~TDummy() { --Count; }
- };
- size_t TDummy::Count = 0;
-
- struct TAlmostDummy {
- static size_t Count;
-
- TAlmostDummy(int j = 0) : Junk(j) { ++Count; }
- TAlmostDummy(const TAlmostDummy& d) : Junk(d.Junk) { ++Count; }
- ~TAlmostDummy() { --Count; }
-
- bool operator==(const TAlmostDummy& r) const { return Junk == r.Junk; };
- bool operator!=(const TAlmostDummy& r) const { return !operator==(r); };
-
- int Junk;
- };
- size_t TAlmostDummy::Count = 0;
-
- struct TNotSimple {
- enum class EType {
- Value,
- Empty,
- Deleted
- } Type_ = EType::Value;
-
- TString Junk = "something"; // to prevent triviality propagation
- int Value = 0;
-
- static int CtorCalls;
- static int DtorCalls;
- static int CopyCtorCalls;
- static int MoveCtorCalls;
-
- TNotSimple() {
- ++CtorCalls;
- }
- explicit TNotSimple(int value)
- : Value(value)
- {
- ++CtorCalls;
- }
-
- TNotSimple(const TNotSimple& rhs) {
- ++CopyCtorCalls;
- Value = rhs.Value;
- Type_ = rhs.Type_;
- }
- TNotSimple(TNotSimple&& rhs) {
- ++MoveCtorCalls;
- Value = rhs.Value;
- Type_ = rhs.Type_;
- }
-
- ~TNotSimple() {
- ++DtorCalls;
- }
-
- TNotSimple& operator=(const TNotSimple& rhs) {
- ++CopyCtorCalls;
- Value = rhs.Value;
- Type_ = rhs.Type_;
- return *this;
- }
- TNotSimple& operator=(TNotSimple&& rhs) {
- ++MoveCtorCalls;
- Value = rhs.Value;
- Type_ = rhs.Type_;
- return *this;
- }
-
- static TNotSimple Empty() {
- TNotSimple ret;
- ret.Type_ = EType::Empty;
- return ret;
- }
-
- static TNotSimple Deleted() {
- TNotSimple ret;
- ret.Type_ = EType::Deleted;
- return ret;
- }
-
- bool operator==(const TNotSimple& rhs) const noexcept {
- return Value == rhs.Value;
- }
-
- static void ResetStats() {
- CtorCalls = 0;
- DtorCalls = 0;
- CopyCtorCalls = 0;
- MoveCtorCalls = 0;
- }
- };
-
- int TNotSimple::CtorCalls = 0;
- int TNotSimple::DtorCalls = 0;
- int TNotSimple::CopyCtorCalls = 0;
- int TNotSimple::MoveCtorCalls = 0;
-
- struct TNotSimpleEmptyMarker {
- using value_type = TNotSimple;
-
- value_type Create() const {
- return TNotSimple::Empty();
- }
-
- bool Equals(const value_type& rhs) const {
- return rhs.Type_ == TNotSimple::EType::Empty;
- }
- };
-
- struct TNotSimpleDeletedMarker {
- using value_type = TNotSimple;
-
- value_type Create() const {
- return TNotSimple::Deleted();
- }
-
- bool Equals(const value_type& rhs) const {
- return rhs.Type_ == TNotSimple::EType::Deleted;
- }
- };
-
- template <class Container>
- void CheckContainersEqual(const Container& a, const Container& b) {
- UNIT_ASSERT_EQUAL(a.Size(), b.Size());
- UNIT_ASSERT_EQUAL(a.Taken(), b.Empty());
- for (typename Container::size_type i = 0; i < a.Size(); ++i) {
- if (a.IsTaken(i)) {
- UNIT_ASSERT(b.IsTaken(i));
- UNIT_ASSERT_EQUAL(a.Node(i), b.Node(i));
- }
- }
- }
-
- template <class Container, class... Args>
- void SmokingTest(typename Container::size_type size, Args&&... args) {
- using size_type = typename Container::size_type;
- using value_type = typename Container::value_type;
-
- Container cont(size, std::forward<Args>(args)...);
- UNIT_ASSERT_EQUAL(cont.Size(), size);
- UNIT_ASSERT_EQUAL(cont.Taken(), 0);
-
- for (size_type i = 0; i < cont.Size(); ++i) {
- UNIT_ASSERT(cont.IsEmpty(i));
- UNIT_ASSERT(!cont.IsTaken(i));
- }
-
- // Filling the container till half
- TVector<size_type> toInsert(cont.Size());
- Iota(toInsert.begin(), toInsert.end(), 0);
- Shuffle(toInsert.begin(), toInsert.end());
- toInsert.resize(toInsert.size() / 2);
- for (auto i : toInsert) {
- UNIT_ASSERT(cont.IsEmpty(i));
- UNIT_ASSERT(!cont.IsTaken(i));
- value_type value(RandomNumber<size_type>(cont.Size()));
- cont.InitNode(i, value);
- UNIT_ASSERT(!cont.IsEmpty(i));
- UNIT_ASSERT(cont.IsTaken(i));
- UNIT_ASSERT_EQUAL(cont.Node(i), value);
- }
- UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size());
-
- // Copy construction test
- auto cont2 = cont;
- CheckContainersEqual(cont, cont2);
-
- // Copy assignment test
- cont2 = cont2.Clone(0);
- UNIT_ASSERT_EQUAL(cont2.Size(), 0);
- UNIT_ASSERT_EQUAL(cont2.Taken(), 0);
-
- // Copy assignment test
- cont2 = cont;
- CheckContainersEqual(cont, cont2);
-
- // Move construction test
- auto cont3 = std::move(cont2);
- UNIT_ASSERT_EQUAL(cont2.Size(), 0);
- CheckContainersEqual(cont, cont3);
-
- // Move assignment test
- cont2 = std::move(cont3);
- UNIT_ASSERT_EQUAL(cont3.Size(), 0);
- CheckContainersEqual(cont, cont2);
- }
-}
-
-Y_UNIT_TEST_SUITE(TFlatContainerTest) {
- Y_UNIT_TEST(SmokingTest) {
- SmokingTest<TFlatContainer<int>>(INIT_SIZE);
- }
-
- Y_UNIT_TEST(SmokingTestNotSimpleType) {
- TNotSimple::ResetStats();
- SmokingTest<TFlatContainer<TNotSimple>>(INIT_SIZE);
-
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
- TNotSimple::DtorCalls);
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */);
- UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, INIT_SIZE / 2 /* removed filling temporary */
- + INIT_SIZE / 2 /* removed while cloning */
- + INIT_SIZE /* 3 containers dtors */);
- UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE / 2 /* 3 created while filling */
- + INIT_SIZE / 2 /* created while copy constructing */
- + INIT_SIZE / 2/* created while copy assigning */);
- UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
- }
-
- Y_UNIT_TEST(DummyHalfSizeTest) {
- using TContainer = TFlatContainer<TDummy>;
- using size_type = typename TContainer::size_type;
-
- {
- TContainer cont(INIT_SIZE);
- UNIT_ASSERT_EQUAL(TDummy::Count, 0);
-
- TVector<size_type> toInsert(cont.Size());
- Iota(toInsert.begin(), toInsert.end(), 0);
- Shuffle(toInsert.begin(), toInsert.end());
- toInsert.resize(toInsert.size() / 2);
- for (auto i : toInsert) {
- UNIT_ASSERT(cont.IsEmpty(i));
- UNIT_ASSERT(!cont.IsTaken(i));
- cont.InitNode(i);
- UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken());
- UNIT_ASSERT(!cont.IsEmpty(i));
- UNIT_ASSERT(cont.IsTaken(i));
- }
- UNIT_ASSERT_EQUAL(cont.Taken(), cont.Size() / 2);
- UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken());
- }
- UNIT_ASSERT_EQUAL(TDummy::Count, 0);
- }
-
- Y_UNIT_TEST(DeleteTest) {
- using TContainer = TFlatContainer<TDummy>;
- using size_type = typename TContainer::size_type;
-
- TContainer cont(INIT_SIZE);
- auto idx = RandomNumber<size_type>(INIT_SIZE);
- UNIT_ASSERT(!cont.IsTaken(idx));
- UNIT_ASSERT(!cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TDummy::Count, 0);
-
- cont.InitNode(idx);
- UNIT_ASSERT_EQUAL(cont.Taken(), 1);
- UNIT_ASSERT(cont.IsTaken(idx));
- UNIT_ASSERT(!cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TDummy::Count, 1);
-
- cont.DeleteNode(idx);
- UNIT_ASSERT(!cont.IsTaken(idx));
- UNIT_ASSERT(cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TDummy::Count, 0);
- }
-}
-
-Y_UNIT_TEST_SUITE(TDenseContainerTest) {
- Y_UNIT_TEST(SmokingTest) {
- SmokingTest<TDenseContainer<int, NSet::TStaticValueMarker<-1>>>(INIT_SIZE);
- }
-
- Y_UNIT_TEST(NotSimpleTypeSmokingTest) {
- TNotSimple::ResetStats();
- SmokingTest<TDenseContainer<TNotSimple, TNotSimpleEmptyMarker>>(INIT_SIZE);
-
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
- TNotSimple::DtorCalls);
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */
- + 2 /* created by empty marker */);
- UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */
- + INIT_SIZE /* half removed while resetting in container,
- half removed inserted temporary */
- + INIT_SIZE /* removed while cloning */
- + 1 /* removed empty marker temporary */
- + INIT_SIZE * 2 /* 3 containers dtors */);
- UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */
- + INIT_SIZE / 2 /* 3 created while filling */
- + INIT_SIZE /* created while copy constructing */
- + INIT_SIZE /* created while copy assigning */);
- UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
- }
-
- Y_UNIT_TEST(RemovalContainerSmokingTest) {
- SmokingTest<TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>,
- NSet::TStaticValueMarker<-2>>>(INIT_SIZE);
- }
-
- Y_UNIT_TEST(NotSimpleTypeRemovalContainerSmokingTest) {
- TNotSimple::ResetStats();
- SmokingTest<TRemovalDenseContainer<TNotSimple, TNotSimpleEmptyMarker,
- TNotSimpleDeletedMarker>>(INIT_SIZE);
-
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
- TNotSimple::DtorCalls);
- UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */
- + 2 /* created by empty marker */);
- UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */
- + INIT_SIZE /* half removed while resetting in container,
- half removed inserted temporary */
- + INIT_SIZE /* removed while cloning */
- + 1 /* removed empty marker temporary */
- + INIT_SIZE * 2 /* 3 containers dtors */);
- UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */
- + INIT_SIZE / 2 /* 3 created while filling */
- + INIT_SIZE /* created while copy constructing */
- + INIT_SIZE /* created while copy assigning */);
- UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
- }
-
- Y_UNIT_TEST(DummyHalfSizeTest) {
- using TContainer = TDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>>;
- using size_type = typename TContainer::size_type;
-
- {
- TContainer cont(INIT_SIZE, TAlmostDummy{-1});
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); // 1 for empty marker
-
- TVector<size_type> toInsert(cont.Size());
- Iota(toInsert.begin(), toInsert.end(), 0);
- Shuffle(toInsert.begin(), toInsert.end());
- toInsert.resize(toInsert.size() / 2);
- for (auto i : toInsert) {
- UNIT_ASSERT(cont.IsEmpty(i));
- UNIT_ASSERT(!cont.IsTaken(i));
- cont.InitNode(i, (int)RandomNumber<size_type>(cont.Size()));
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1);
- UNIT_ASSERT(!cont.IsEmpty(i));
- UNIT_ASSERT(cont.IsTaken(i));
- }
- UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size());
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1);
- }
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, 0);
- }
-
- Y_UNIT_TEST(DeleteTest) {
- using TContainer = TRemovalDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>,
- NSet::TEqValueMarker<TAlmostDummy>>;
- using size_type = typename TContainer::size_type;
-
- TContainer cont(INIT_SIZE, TAlmostDummy{ -2 }, TAlmostDummy{ -1 });
- auto idx = RandomNumber<size_type>(cont.Size());
- UNIT_ASSERT(!cont.IsTaken(idx));
- UNIT_ASSERT(!cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); // 2 for markers
-
- cont.InitNode(idx, (int)RandomNumber<size_type>(cont.Size()));
- UNIT_ASSERT_EQUAL(cont.Taken(), 1);
- UNIT_ASSERT(cont.IsTaken(idx));
- UNIT_ASSERT(!cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2);
-
- cont.DeleteNode(idx);
- UNIT_ASSERT(!cont.IsTaken(idx));
- UNIT_ASSERT(cont.IsDeleted(idx));
- UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2);
- }
-
- Y_UNIT_TEST(FancyInitsTest) {
- {
- using TContainer = TDenseContainer<int>;
- TContainer cont{ INIT_SIZE, -1 };
- }
- {
- using TContainer = TDenseContainer<int, NSet::TStaticValueMarker<-1>>;
- TContainer cont{ INIT_SIZE };
- static_assert(!std::is_constructible_v<TContainer, size_t, int>);
- }
- {
- using TContainer = TDenseContainer<int, NSet::TEqValueMarker<int>>;
- TContainer cont{ INIT_SIZE, -1 };
- TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 } };
- }
- {
- using TContainer = TRemovalDenseContainer<int>;
- TContainer cont{ INIT_SIZE, -1, -2 };
- TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 },
- NSet::TEqValueMarker<int>{ -2 } };
- }
- {
- using TContainer = TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>,
- NSet::TStaticValueMarker<-1>>;
- TContainer cont{ INIT_SIZE };
- static_assert(!std::is_constructible_v<TContainer, size_t, int>);
- static_assert(!std::is_constructible_v<TContainer, size_t, int, int>);
- }
- }
-}
+
+#include <util/generic/algorithm.h>
+#include <util/random/random.h>
+#include <util/random/shuffle.h>
+
+using namespace NFlatHash;
+
+namespace {
+ constexpr size_t INIT_SIZE = 128;
+
+ struct TDummy {
+ static size_t Count;
+
+ TDummy() { ++Count; }
+ TDummy(const TDummy&) { ++Count; }
+ ~TDummy() { --Count; }
+ };
+ size_t TDummy::Count = 0;
+
+ struct TAlmostDummy {
+ static size_t Count;
+
+ TAlmostDummy(int j = 0) : Junk(j) { ++Count; }
+ TAlmostDummy(const TAlmostDummy& d) : Junk(d.Junk) { ++Count; }
+ ~TAlmostDummy() { --Count; }
+
+ bool operator==(const TAlmostDummy& r) const { return Junk == r.Junk; };
+ bool operator!=(const TAlmostDummy& r) const { return !operator==(r); };
+
+ int Junk;
+ };
+ size_t TAlmostDummy::Count = 0;
+
+ struct TNotSimple {
+ enum class EType {
+ Value,
+ Empty,
+ Deleted
+ } Type_ = EType::Value;
+
+ TString Junk = "something"; // to prevent triviality propagation
+ int Value = 0;
+
+ static int CtorCalls;
+ static int DtorCalls;
+ static int CopyCtorCalls;
+ static int MoveCtorCalls;
+
+ TNotSimple() {
+ ++CtorCalls;
+ }
+ explicit TNotSimple(int value)
+ : Value(value)
+ {
+ ++CtorCalls;
+ }
+
+ TNotSimple(const TNotSimple& rhs) {
+ ++CopyCtorCalls;
+ Value = rhs.Value;
+ Type_ = rhs.Type_;
+ }
+ TNotSimple(TNotSimple&& rhs) {
+ ++MoveCtorCalls;
+ Value = rhs.Value;
+ Type_ = rhs.Type_;
+ }
+
+ ~TNotSimple() {
+ ++DtorCalls;
+ }
+
+ TNotSimple& operator=(const TNotSimple& rhs) {
+ ++CopyCtorCalls;
+ Value = rhs.Value;
+ Type_ = rhs.Type_;
+ return *this;
+ }
+ TNotSimple& operator=(TNotSimple&& rhs) {
+ ++MoveCtorCalls;
+ Value = rhs.Value;
+ Type_ = rhs.Type_;
+ return *this;
+ }
+
+ static TNotSimple Empty() {
+ TNotSimple ret;
+ ret.Type_ = EType::Empty;
+ return ret;
+ }
+
+ static TNotSimple Deleted() {
+ TNotSimple ret;
+ ret.Type_ = EType::Deleted;
+ return ret;
+ }
+
+ bool operator==(const TNotSimple& rhs) const noexcept {
+ return Value == rhs.Value;
+ }
+
+ static void ResetStats() {
+ CtorCalls = 0;
+ DtorCalls = 0;
+ CopyCtorCalls = 0;
+ MoveCtorCalls = 0;
+ }
+ };
+
+ int TNotSimple::CtorCalls = 0;
+ int TNotSimple::DtorCalls = 0;
+ int TNotSimple::CopyCtorCalls = 0;
+ int TNotSimple::MoveCtorCalls = 0;
+
+ struct TNotSimpleEmptyMarker {
+ using value_type = TNotSimple;
+
+ value_type Create() const {
+ return TNotSimple::Empty();
+ }
+
+ bool Equals(const value_type& rhs) const {
+ return rhs.Type_ == TNotSimple::EType::Empty;
+ }
+ };
+
+ struct TNotSimpleDeletedMarker {
+ using value_type = TNotSimple;
+
+ value_type Create() const {
+ return TNotSimple::Deleted();
+ }
+
+ bool Equals(const value_type& rhs) const {
+ return rhs.Type_ == TNotSimple::EType::Deleted;
+ }
+ };
+
+ template <class Container>
+ void CheckContainersEqual(const Container& a, const Container& b) {
+ UNIT_ASSERT_EQUAL(a.Size(), b.Size());
+ UNIT_ASSERT_EQUAL(a.Taken(), b.Empty());
+ for (typename Container::size_type i = 0; i < a.Size(); ++i) {
+ if (a.IsTaken(i)) {
+ UNIT_ASSERT(b.IsTaken(i));
+ UNIT_ASSERT_EQUAL(a.Node(i), b.Node(i));
+ }
+ }
+ }
+
+ template <class Container, class... Args>
+ void SmokingTest(typename Container::size_type size, Args&&... args) {
+ using size_type = typename Container::size_type;
+ using value_type = typename Container::value_type;
+
+ Container cont(size, std::forward<Args>(args)...);
+ UNIT_ASSERT_EQUAL(cont.Size(), size);
+ UNIT_ASSERT_EQUAL(cont.Taken(), 0);
+
+ for (size_type i = 0; i < cont.Size(); ++i) {
+ UNIT_ASSERT(cont.IsEmpty(i));
+ UNIT_ASSERT(!cont.IsTaken(i));
+ }
+
+ // Filling the container till half
+ TVector<size_type> toInsert(cont.Size());
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ Shuffle(toInsert.begin(), toInsert.end());
+ toInsert.resize(toInsert.size() / 2);
+ for (auto i : toInsert) {
+ UNIT_ASSERT(cont.IsEmpty(i));
+ UNIT_ASSERT(!cont.IsTaken(i));
+ value_type value(RandomNumber<size_type>(cont.Size()));
+ cont.InitNode(i, value);
+ UNIT_ASSERT(!cont.IsEmpty(i));
+ UNIT_ASSERT(cont.IsTaken(i));
+ UNIT_ASSERT_EQUAL(cont.Node(i), value);
+ }
+ UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size());
+
+ // Copy construction test
+ auto cont2 = cont;
+ CheckContainersEqual(cont, cont2);
+
+ // Copy assignment test
+ cont2 = cont2.Clone(0);
+ UNIT_ASSERT_EQUAL(cont2.Size(), 0);
+ UNIT_ASSERT_EQUAL(cont2.Taken(), 0);
+
+ // Copy assignment test
+ cont2 = cont;
+ CheckContainersEqual(cont, cont2);
+
+ // Move construction test
+ auto cont3 = std::move(cont2);
+ UNIT_ASSERT_EQUAL(cont2.Size(), 0);
+ CheckContainersEqual(cont, cont3);
+
+ // Move assignment test
+ cont2 = std::move(cont3);
+ UNIT_ASSERT_EQUAL(cont3.Size(), 0);
+ CheckContainersEqual(cont, cont2);
+ }
+}
+
+Y_UNIT_TEST_SUITE(TFlatContainerTest) {
+ Y_UNIT_TEST(SmokingTest) {
+ SmokingTest<TFlatContainer<int>>(INIT_SIZE);
+ }
+
+ Y_UNIT_TEST(SmokingTestNotSimpleType) {
+ TNotSimple::ResetStats();
+ SmokingTest<TFlatContainer<TNotSimple>>(INIT_SIZE);
+
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
+ TNotSimple::DtorCalls);
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */);
+ UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, INIT_SIZE / 2 /* removed filling temporary */
+ + INIT_SIZE / 2 /* removed while cloning */
+ + INIT_SIZE /* 3 containers dtors */);
+ UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE / 2 /* 3 created while filling */
+ + INIT_SIZE / 2 /* created while copy constructing */
+ + INIT_SIZE / 2/* created while copy assigning */);
+ UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
+ }
+
+ Y_UNIT_TEST(DummyHalfSizeTest) {
+ using TContainer = TFlatContainer<TDummy>;
+ using size_type = typename TContainer::size_type;
+
+ {
+ TContainer cont(INIT_SIZE);
+ UNIT_ASSERT_EQUAL(TDummy::Count, 0);
+
+ TVector<size_type> toInsert(cont.Size());
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ Shuffle(toInsert.begin(), toInsert.end());
+ toInsert.resize(toInsert.size() / 2);
+ for (auto i : toInsert) {
+ UNIT_ASSERT(cont.IsEmpty(i));
+ UNIT_ASSERT(!cont.IsTaken(i));
+ cont.InitNode(i);
+ UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken());
+ UNIT_ASSERT(!cont.IsEmpty(i));
+ UNIT_ASSERT(cont.IsTaken(i));
+ }
+ UNIT_ASSERT_EQUAL(cont.Taken(), cont.Size() / 2);
+ UNIT_ASSERT_EQUAL(TDummy::Count, cont.Taken());
+ }
+ UNIT_ASSERT_EQUAL(TDummy::Count, 0);
+ }
+
+ Y_UNIT_TEST(DeleteTest) {
+ using TContainer = TFlatContainer<TDummy>;
+ using size_type = typename TContainer::size_type;
+
+ TContainer cont(INIT_SIZE);
+ auto idx = RandomNumber<size_type>(INIT_SIZE);
+ UNIT_ASSERT(!cont.IsTaken(idx));
+ UNIT_ASSERT(!cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TDummy::Count, 0);
+
+ cont.InitNode(idx);
+ UNIT_ASSERT_EQUAL(cont.Taken(), 1);
+ UNIT_ASSERT(cont.IsTaken(idx));
+ UNIT_ASSERT(!cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TDummy::Count, 1);
+
+ cont.DeleteNode(idx);
+ UNIT_ASSERT(!cont.IsTaken(idx));
+ UNIT_ASSERT(cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TDummy::Count, 0);
+ }
+}
+
+Y_UNIT_TEST_SUITE(TDenseContainerTest) {
+ Y_UNIT_TEST(SmokingTest) {
+ SmokingTest<TDenseContainer<int, NSet::TStaticValueMarker<-1>>>(INIT_SIZE);
+ }
+
+ Y_UNIT_TEST(NotSimpleTypeSmokingTest) {
+ TNotSimple::ResetStats();
+ SmokingTest<TDenseContainer<TNotSimple, TNotSimpleEmptyMarker>>(INIT_SIZE);
+
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
+ TNotSimple::DtorCalls);
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */
+ + 2 /* created by empty marker */);
+ UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */
+ + INIT_SIZE /* half removed while resetting in container,
+ half removed inserted temporary */
+ + INIT_SIZE /* removed while cloning */
+ + 1 /* removed empty marker temporary */
+ + INIT_SIZE * 2 /* 3 containers dtors */);
+ UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */
+ + INIT_SIZE / 2 /* 3 created while filling */
+ + INIT_SIZE /* created while copy constructing */
+ + INIT_SIZE /* created while copy assigning */);
+ UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
+ }
+
+ Y_UNIT_TEST(RemovalContainerSmokingTest) {
+ SmokingTest<TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>,
+ NSet::TStaticValueMarker<-2>>>(INIT_SIZE);
+ }
+
+ Y_UNIT_TEST(NotSimpleTypeRemovalContainerSmokingTest) {
+ TNotSimple::ResetStats();
+ SmokingTest<TRemovalDenseContainer<TNotSimple, TNotSimpleEmptyMarker,
+ TNotSimpleDeletedMarker>>(INIT_SIZE);
+
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls + TNotSimple::CopyCtorCalls + TNotSimple::MoveCtorCalls,
+ TNotSimple::DtorCalls);
+ UNIT_ASSERT_EQUAL(TNotSimple::CtorCalls, INIT_SIZE / 2 /* created while filling */
+ + 2 /* created by empty marker */);
+ UNIT_ASSERT_EQUAL(TNotSimple::DtorCalls, 1 /* removed empty marker temporary */
+ + INIT_SIZE /* half removed while resetting in container,
+ half removed inserted temporary */
+ + INIT_SIZE /* removed while cloning */
+ + 1 /* removed empty marker temporary */
+ + INIT_SIZE * 2 /* 3 containers dtors */);
+ UNIT_ASSERT_EQUAL(TNotSimple::CopyCtorCalls, INIT_SIZE /* created while constructing */
+ + INIT_SIZE / 2 /* 3 created while filling */
+ + INIT_SIZE /* created while copy constructing */
+ + INIT_SIZE /* created while copy assigning */);
+ UNIT_ASSERT_EQUAL(TNotSimple::MoveCtorCalls, 0);
+ }
+
+ Y_UNIT_TEST(DummyHalfSizeTest) {
+ using TContainer = TDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>>;
+ using size_type = typename TContainer::size_type;
+
+ {
+ TContainer cont(INIT_SIZE, TAlmostDummy{-1});
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1); // 1 for empty marker
+
+ TVector<size_type> toInsert(cont.Size());
+ Iota(toInsert.begin(), toInsert.end(), 0);
+ Shuffle(toInsert.begin(), toInsert.end());
+ toInsert.resize(toInsert.size() / 2);
+ for (auto i : toInsert) {
+ UNIT_ASSERT(cont.IsEmpty(i));
+ UNIT_ASSERT(!cont.IsTaken(i));
+ cont.InitNode(i, (int)RandomNumber<size_type>(cont.Size()));
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1);
+ UNIT_ASSERT(!cont.IsEmpty(i));
+ UNIT_ASSERT(cont.IsTaken(i));
+ }
+ UNIT_ASSERT_EQUAL(cont.Taken(), toInsert.size());
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 1);
+ }
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, 0);
+ }
+
+ Y_UNIT_TEST(DeleteTest) {
+ using TContainer = TRemovalDenseContainer<TAlmostDummy, NSet::TEqValueMarker<TAlmostDummy>,
+ NSet::TEqValueMarker<TAlmostDummy>>;
+ using size_type = typename TContainer::size_type;
+
+ TContainer cont(INIT_SIZE, TAlmostDummy{ -2 }, TAlmostDummy{ -1 });
+ auto idx = RandomNumber<size_type>(cont.Size());
+ UNIT_ASSERT(!cont.IsTaken(idx));
+ UNIT_ASSERT(!cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2); // 2 for markers
+
+ cont.InitNode(idx, (int)RandomNumber<size_type>(cont.Size()));
+ UNIT_ASSERT_EQUAL(cont.Taken(), 1);
+ UNIT_ASSERT(cont.IsTaken(idx));
+ UNIT_ASSERT(!cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2);
+
+ cont.DeleteNode(idx);
+ UNIT_ASSERT(!cont.IsTaken(idx));
+ UNIT_ASSERT(cont.IsDeleted(idx));
+ UNIT_ASSERT_EQUAL(TAlmostDummy::Count, cont.Size() + 2);
+ }
+
+ Y_UNIT_TEST(FancyInitsTest) {
+ {
+ using TContainer = TDenseContainer<int>;
+ TContainer cont{ INIT_SIZE, -1 };
+ }
+ {
+ using TContainer = TDenseContainer<int, NSet::TStaticValueMarker<-1>>;
+ TContainer cont{ INIT_SIZE };
+ static_assert(!std::is_constructible_v<TContainer, size_t, int>);
+ }
+ {
+ using TContainer = TDenseContainer<int, NSet::TEqValueMarker<int>>;
+ TContainer cont{ INIT_SIZE, -1 };
+ TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 } };
+ }
+ {
+ using TContainer = TRemovalDenseContainer<int>;
+ TContainer cont{ INIT_SIZE, -1, -2 };
+ TContainer cont2{ INIT_SIZE, NSet::TEqValueMarker<int>{ -1 },
+ NSet::TEqValueMarker<int>{ -2 } };
+ }
+ {
+ using TContainer = TRemovalDenseContainer<int, NSet::TStaticValueMarker<-1>,
+ NSet::TStaticValueMarker<-1>>;
+ TContainer cont{ INIT_SIZE };
+ static_assert(!std::is_constructible_v<TContainer, size_t, int>);
+ static_assert(!std::is_constructible_v<TContainer, size_t, int, int>);
+ }
+ }
+}
diff --git a/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp
index 10111b74da..0b77bf043f 100644
--- a/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp
+++ b/library/cpp/containers/flat_hash/lib/ut/iterator_ut.cpp
@@ -1,85 +1,85 @@
#include <library/cpp/containers/flat_hash/lib/iterator.h>
#include <library/cpp/containers/flat_hash/lib/containers.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/random/random.h>
-#include <util/generic/algorithm.h>
-
-using namespace NFlatHash;
-
-namespace {
- constexpr size_t INIT_SIZE = 128;
-
- template <class Container>
- void SmokingTest(Container& cont) {
- using value_type = typename Container::value_type;
- using iterator = TIterator<Container, value_type>;
- using size_type = typename Container::size_type;
-
- iterator f(&cont), l(&cont, cont.Size());
- UNIT_ASSERT_EQUAL(f, l);
- UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken());
-
- TVector<std::pair<size_type, value_type>> toAdd{
- { 0, (int)RandomNumber<size_type>(INIT_SIZE) },
- { 1 + RandomNumber<size_type>(INIT_SIZE - 2), (int)RandomNumber<size_type>(INIT_SIZE) },
- { INIT_SIZE - 1, (int)RandomNumber<size_type>(INIT_SIZE) }
- };
-
- for (const auto& p : toAdd) {
- UNIT_ASSERT(cont.IsEmpty(p.first));
- cont.InitNode(p.first, p.second);
- }
- UNIT_ASSERT_EQUAL(cont.Size(), INIT_SIZE);
- f = iterator{ &cont };
- l = iterator{ &cont, INIT_SIZE };
- UNIT_ASSERT_UNEQUAL(f, l);
- UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken());
-
- TVector<value_type> added(f, l);
- UNIT_ASSERT(::Equal(toAdd.begin(), toAdd.end(), added.begin(), [](const auto& p, auto v) {
- return p.second == v;
- }));
- }
-
- template <class Container>
- void ConstTest(Container& cont) {
- using value_type = typename Container::value_type;
- using iterator = TIterator<Container, value_type>;
- using const_iterator = TIterator<const Container, const value_type>;
-
- iterator it{ &cont, INIT_SIZE / 2 };
- const_iterator cit1{ it };
- const_iterator cit2{ &cont, INIT_SIZE / 2 };
-
- UNIT_ASSERT_EQUAL(cit1, cit2);
-
- static_assert(std::is_same<decltype(*it), value_type&>::value);
- static_assert(std::is_same<decltype(*cit1), const value_type&>::value);
- }
-}
-
-Y_UNIT_TEST_SUITE(TIteratorTest) {
- Y_UNIT_TEST(SmokingTest) {
- {
- TFlatContainer<int> cont(INIT_SIZE);
- SmokingTest(cont);
- }
- {
- TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE);
- SmokingTest(cont);
- }
- }
-
- Y_UNIT_TEST(ConstTest) {
- {
- TFlatContainer<int> cont(INIT_SIZE);
- ConstTest(cont);
- }
- {
- TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE);
- ConstTest(cont);
- }
- }
-}
+
+#include <util/random/random.h>
+#include <util/generic/algorithm.h>
+
+using namespace NFlatHash;
+
+namespace {
+ constexpr size_t INIT_SIZE = 128;
+
+ template <class Container>
+ void SmokingTest(Container& cont) {
+ using value_type = typename Container::value_type;
+ using iterator = TIterator<Container, value_type>;
+ using size_type = typename Container::size_type;
+
+ iterator f(&cont), l(&cont, cont.Size());
+ UNIT_ASSERT_EQUAL(f, l);
+ UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken());
+
+ TVector<std::pair<size_type, value_type>> toAdd{
+ { 0, (int)RandomNumber<size_type>(INIT_SIZE) },
+ { 1 + RandomNumber<size_type>(INIT_SIZE - 2), (int)RandomNumber<size_type>(INIT_SIZE) },
+ { INIT_SIZE - 1, (int)RandomNumber<size_type>(INIT_SIZE) }
+ };
+
+ for (const auto& p : toAdd) {
+ UNIT_ASSERT(cont.IsEmpty(p.first));
+ cont.InitNode(p.first, p.second);
+ }
+ UNIT_ASSERT_EQUAL(cont.Size(), INIT_SIZE);
+ f = iterator{ &cont };
+ l = iterator{ &cont, INIT_SIZE };
+ UNIT_ASSERT_UNEQUAL(f, l);
+ UNIT_ASSERT_EQUAL((size_type)std::distance(f, l), cont.Taken());
+
+ TVector<value_type> added(f, l);
+ UNIT_ASSERT(::Equal(toAdd.begin(), toAdd.end(), added.begin(), [](const auto& p, auto v) {
+ return p.second == v;
+ }));
+ }
+
+ template <class Container>
+ void ConstTest(Container& cont) {
+ using value_type = typename Container::value_type;
+ using iterator = TIterator<Container, value_type>;
+ using const_iterator = TIterator<const Container, const value_type>;
+
+ iterator it{ &cont, INIT_SIZE / 2 };
+ const_iterator cit1{ it };
+ const_iterator cit2{ &cont, INIT_SIZE / 2 };
+
+ UNIT_ASSERT_EQUAL(cit1, cit2);
+
+ static_assert(std::is_same<decltype(*it), value_type&>::value);
+ static_assert(std::is_same<decltype(*cit1), const value_type&>::value);
+ }
+}
+
+Y_UNIT_TEST_SUITE(TIteratorTest) {
+ Y_UNIT_TEST(SmokingTest) {
+ {
+ TFlatContainer<int> cont(INIT_SIZE);
+ SmokingTest(cont);
+ }
+ {
+ TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE);
+ SmokingTest(cont);
+ }
+ }
+
+ Y_UNIT_TEST(ConstTest) {
+ {
+ TFlatContainer<int> cont(INIT_SIZE);
+ ConstTest(cont);
+ }
+ {
+ TDenseContainer<int, NSet::TStaticValueMarker<-1>> cont(INIT_SIZE);
+ ConstTest(cont);
+ }
+ }
+}
diff --git a/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp
index 7d709fdaa5..593f8cbb1b 100644
--- a/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp
+++ b/library/cpp/containers/flat_hash/lib/ut/probings_ut.cpp
@@ -1,34 +1,34 @@
#include <library/cpp/containers/flat_hash/lib/probings.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NFlatHash;
-
-namespace {
- struct TDummySizeFitter {
- constexpr auto EvalIndex(size_t idx, size_t) const {
- return idx;
- }
- };
-
+
+using namespace NFlatHash;
+
+namespace {
+ struct TDummySizeFitter {
+ constexpr auto EvalIndex(size_t idx, size_t) const {
+ return idx;
+ }
+ };
+
constexpr TDummySizeFitter SIZE_FITTER;
-
- auto atLeast13 = [](size_t idx) { return idx >= 13; };
-}
-
-Y_UNIT_TEST_SUITE(TProbingsTest) {
- Y_UNIT_TEST(LinearProbingTest) {
- using TProbing = TLinearProbing;
- UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 13);
- }
-
- Y_UNIT_TEST(QuadraticProbingTest) {
- using TProbing = TQuadraticProbing;
- UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 17);
- }
-
- Y_UNIT_TEST(DenseProbingTest) {
- using TProbing = TDenseProbing;
- UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 16);
- }
-}
+
+ auto atLeast13 = [](size_t idx) { return idx >= 13; };
+}
+
+Y_UNIT_TEST_SUITE(TProbingsTest) {
+ Y_UNIT_TEST(LinearProbingTest) {
+ using TProbing = TLinearProbing;
+ UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 13);
+ }
+
+ Y_UNIT_TEST(QuadraticProbingTest) {
+ using TProbing = TQuadraticProbing;
+ UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 17);
+ }
+
+ Y_UNIT_TEST(DenseProbingTest) {
+ using TProbing = TDenseProbing;
+ UNIT_ASSERT_EQUAL(TProbing::FindBucket(SIZE_FITTER, 1, 0, atLeast13), 16);
+ }
+}
diff --git a/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp b/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp
index 52084e734b..4167947ece 100644
--- a/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp
+++ b/library/cpp/containers/flat_hash/lib/ut/size_fitters_ut.cpp
@@ -1,51 +1,51 @@
#include <library/cpp/containers/flat_hash/lib/size_fitters.h>
-
+
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NFlatHash;
-
-Y_UNIT_TEST_SUITE(TAndSizeFitterTest) {
- Y_UNIT_TEST(EvalSizeTest) {
- TAndSizeFitter sf;
- UNIT_ASSERT_EQUAL(sf.EvalSize(5), 8);
- UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8);
- UNIT_ASSERT_EQUAL(sf.EvalSize(13), 16);
- UNIT_ASSERT_EQUAL(sf.EvalSize(25), 32);
- for (size_t i = 1; i < 100; ++i) {
- UNIT_ASSERT_EQUAL(sf.EvalSize(i), FastClp2(i));
- }
- }
-
- Y_UNIT_TEST(EvalIndexTest) {
- TAndSizeFitter sf;
- for (size_t j = 1; j < 10; ++j) {
- sf.Update(1 << j);
- for (size_t i = 0; i < 100; ++i) {
- UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i & ((1 << j) - 1));
- }
- }
- }
-}
-
-Y_UNIT_TEST_SUITE(TModSizeFitterTest) {
- Y_UNIT_TEST(EvalSizeTest) {
- TModSizeFitter sf;
- UNIT_ASSERT_EQUAL(sf.EvalSize(5), 5);
- UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8);
- UNIT_ASSERT_EQUAL(sf.EvalSize(13), 13);
- UNIT_ASSERT_EQUAL(sf.EvalSize(25), 25);
- for (size_t i = 1; i < 100; ++i) {
- UNIT_ASSERT_EQUAL(sf.EvalSize(i), i);
- }
- }
-
- Y_UNIT_TEST(EvalIndexTest) {
- TModSizeFitter sf;
- for (size_t j = 1; j < 10; ++j) {
- sf.Update(1 << j); // just for integrity
- for (size_t i = 0; i < 100; ++i) {
- UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i % (1 << j));
- }
- }
- }
-}
+
+using namespace NFlatHash;
+
+Y_UNIT_TEST_SUITE(TAndSizeFitterTest) {
+ Y_UNIT_TEST(EvalSizeTest) {
+ TAndSizeFitter sf;
+ UNIT_ASSERT_EQUAL(sf.EvalSize(5), 8);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(13), 16);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(25), 32);
+ for (size_t i = 1; i < 100; ++i) {
+ UNIT_ASSERT_EQUAL(sf.EvalSize(i), FastClp2(i));
+ }
+ }
+
+ Y_UNIT_TEST(EvalIndexTest) {
+ TAndSizeFitter sf;
+ for (size_t j = 1; j < 10; ++j) {
+ sf.Update(1 << j);
+ for (size_t i = 0; i < 100; ++i) {
+ UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i & ((1 << j) - 1));
+ }
+ }
+ }
+}
+
+Y_UNIT_TEST_SUITE(TModSizeFitterTest) {
+ Y_UNIT_TEST(EvalSizeTest) {
+ TModSizeFitter sf;
+ UNIT_ASSERT_EQUAL(sf.EvalSize(5), 5);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(8), 8);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(13), 13);
+ UNIT_ASSERT_EQUAL(sf.EvalSize(25), 25);
+ for (size_t i = 1; i < 100; ++i) {
+ UNIT_ASSERT_EQUAL(sf.EvalSize(i), i);
+ }
+ }
+
+ Y_UNIT_TEST(EvalIndexTest) {
+ TModSizeFitter sf;
+ for (size_t j = 1; j < 10; ++j) {
+ sf.Update(1 << j); // just for integrity
+ for (size_t i = 0; i < 100; ++i) {
+ UNIT_ASSERT_EQUAL(sf.EvalIndex(i, 1 << j), i % (1 << j));
+ }
+ }
+ }
+}
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{});
+ }
+}
diff --git a/library/cpp/containers/flat_hash/lib/ut/ya.make b/library/cpp/containers/flat_hash/lib/ut/ya.make
index 5ffbfb2dd8..04d65a8c6e 100644
--- a/library/cpp/containers/flat_hash/lib/ut/ya.make
+++ b/library/cpp/containers/flat_hash/lib/ut/ya.make
@@ -1,17 +1,17 @@
-UNITTEST()
-
-OWNER(tender-bum)
-
-SRCS(
- size_fitters_ut.cpp
- probings_ut.cpp
- containers_ut.cpp
- iterator_ut.cpp
- table_ut.cpp
-)
-
-PEERDIR(
+UNITTEST()
+
+OWNER(tender-bum)
+
+SRCS(
+ size_fitters_ut.cpp
+ probings_ut.cpp
+ containers_ut.cpp
+ iterator_ut.cpp
+ table_ut.cpp
+)
+
+PEERDIR(
library/cpp/containers/flat_hash/lib
-)
-
-END()
+)
+
+END()