diff options
author | tender-bum <tender-bum@yandex-team.ru> | 2022-02-10 16:50:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:50:01 +0300 |
commit | c78b06a63de7beec995c1007bc5332bdf3d75b69 (patch) | |
tree | 729de992758f40b85278d4abaad655be5dd68dbc /library/cpp/containers/flat_hash/lib/fuzz | |
parent | 95ab23a39b5482a434361566cabdd5b0a433cb43 (diff) | |
download | ydb-c78b06a63de7beec995c1007bc5332bdf3d75b69.tar.gz |
Restoring authorship annotation for <tender-bum@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/containers/flat_hash/lib/fuzz')
8 files changed, 378 insertions, 378 deletions
diff --git a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp index 9b4cb4c983..7ddc13053f 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/fuzz.cpp @@ -3,58 +3,58 @@ #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/expanders.h> - + #include <library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h> - -#include <util/generic/hash.h> -#include <util/generic/xrange.h> -#include <util/generic/bt_exception.h> - -using namespace NFlatHash; - -namespace { - -template <class Key, class T> -using TDenseModMap = NFlatHash::TMap<Key, - T, - THash<Key>, - std::equal_to<Key>, - TRemovalDenseContainer<std::pair<const Key, T>, - NMap::TEqValueMarker<Key, T>, - NMap::TEqValueMarker<Key, T>>, - TDenseProbing, - TAndSizeFitter, - TSimpleExpander>; - -NFuzz::EActionType EvalType(ui8 data) { - return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); -} - -ui8 EvalKey(ui8 data) { - return data & 0b11111; -} - -ui8 EvalValue() { - return RandomNumber<ui8>(); -} - -} // namespace - -#include <util/datetime/base.h> - -extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { - THashMap<ui8, ui8> etalon; - // We assume, that markers can't be produced by EvalKey function. - TDenseModMap<ui8, ui8> testee(8, - (1 << 5), // Deleted marker - (1 << 6)); // Empty marker - - for (auto i : xrange(wireSize)) { - auto data = wireData[i]; - - NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); - NFuzz::CheckInvariants(etalon, testee); - } - - return 0; -} + +#include <util/generic/hash.h> +#include <util/generic/xrange.h> +#include <util/generic/bt_exception.h> + +using namespace NFlatHash; + +namespace { + +template <class Key, class T> +using TDenseModMap = NFlatHash::TMap<Key, + T, + THash<Key>, + std::equal_to<Key>, + TRemovalDenseContainer<std::pair<const Key, T>, + NMap::TEqValueMarker<Key, T>, + NMap::TEqValueMarker<Key, T>>, + TDenseProbing, + TAndSizeFitter, + TSimpleExpander>; + +NFuzz::EActionType EvalType(ui8 data) { + return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); +} + +ui8 EvalKey(ui8 data) { + return data & 0b11111; +} + +ui8 EvalValue() { + return RandomNumber<ui8>(); +} + +} // namespace + +#include <util/datetime/base.h> + +extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { + THashMap<ui8, ui8> etalon; + // We assume, that markers can't be produced by EvalKey function. + TDenseModMap<ui8, ui8> testee(8, + (1 << 5), // Deleted marker + (1 << 6)); // Empty marker + + for (auto i : xrange(wireSize)) { + auto data = wireData[i]; + + NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); + NFuzz::CheckInvariants(etalon, testee); + } + + return 0; +} diff --git a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make index 3a5d3d6d8c..a43dba1f61 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/dense_map_fuzz/ya.make @@ -1,19 +1,19 @@ -FUZZ() - -OWNER( - tender-bum -) - -SRCS( - fuzz.cpp -) - -PEERDIR( +FUZZ() + +OWNER( + tender-bum +) + +SRCS( + fuzz.cpp +) + +PEERDIR( library/cpp/containers/flat_hash/lib/fuzz/fuzz_common -) - -SIZE(LARGE) - -TAG(ya:fat) - -END() +) + +SIZE(LARGE) + +TAG(ya:fat) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp index 7fb73af0e9..7730dc889b 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/fuzz.cpp @@ -3,51 +3,51 @@ #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/expanders.h> - + #include <library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h> - -#include <util/generic/hash.h> -#include <util/generic/xrange.h> -#include <util/generic/bt_exception.h> - -using namespace NFlatHash; - -namespace { - -template <class Key, class T> -using TFlatLinearModMap = NFlatHash::TMap<Key, - T, - THash<Key>, - std::equal_to<Key>, - TFlatContainer<std::pair<const Key, T>>, - TLinearProbing, - TAndSizeFitter, - TSimpleExpander>; - -NFuzz::EActionType EvalType(ui8 data) { - return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); -} - -ui8 EvalKey(ui8 data) { - return data & 0b11111; -} - -ui8 EvalValue() { - return RandomNumber<ui8>(); -} - -} // namespace - -extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { - THashMap<ui8, ui8> etalon; - TFlatLinearModMap<ui8, ui8> testee; - - for (auto i : xrange(wireSize)) { - auto data = wireData[i]; - - NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); - NFuzz::CheckInvariants(etalon, testee); - } - - return 0; -} + +#include <util/generic/hash.h> +#include <util/generic/xrange.h> +#include <util/generic/bt_exception.h> + +using namespace NFlatHash; + +namespace { + +template <class Key, class T> +using TFlatLinearModMap = NFlatHash::TMap<Key, + T, + THash<Key>, + std::equal_to<Key>, + TFlatContainer<std::pair<const Key, T>>, + TLinearProbing, + TAndSizeFitter, + TSimpleExpander>; + +NFuzz::EActionType EvalType(ui8 data) { + return static_cast<NFuzz::EActionType>((data >> 5) & 0b111); +} + +ui8 EvalKey(ui8 data) { + return data & 0b11111; +} + +ui8 EvalValue() { + return RandomNumber<ui8>(); +} + +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const ui8* const wireData, const size_t wireSize) { + THashMap<ui8, ui8> etalon; + TFlatLinearModMap<ui8, ui8> testee; + + for (auto i : xrange(wireSize)) { + auto data = wireData[i]; + + NFuzz::MakeAction(etalon, testee, EvalKey(data), EvalValue(), EvalType(data)); + NFuzz::CheckInvariants(etalon, testee); + } + + return 0; +} diff --git a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make index 3a5d3d6d8c..a43dba1f61 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/flat_map_fuzz/ya.make @@ -1,19 +1,19 @@ -FUZZ() - -OWNER( - tender-bum -) - -SRCS( - fuzz.cpp -) - -PEERDIR( +FUZZ() + +OWNER( + tender-bum +) + +SRCS( + fuzz.cpp +) + +PEERDIR( library/cpp/containers/flat_hash/lib/fuzz/fuzz_common -) - -SIZE(LARGE) - -TAG(ya:fat) - -END() +) + +SIZE(LARGE) + +TAG(ya:fat) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp index efc2973d18..aa87b16e98 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.cpp @@ -1 +1 @@ -#include "fuzz_common.h" +#include "fuzz_common.h" diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h index 71a123d9cf..fa1885990f 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/fuzz_common.h @@ -1,223 +1,223 @@ -#pragma once - -#include <util/generic/bt_exception.h> -#include <util/generic/vector.h> -#include <util/generic/xrange.h> - -#include <util/random/random.h> - -namespace NFlatHash::NFuzz { - -#define FUZZ_ASSERT(cond) \ - Y_ENSURE_EX(cond, TWithBackTrace<yexception>() << Y_STRINGIZE(cond) << " assertion failed ") - -#define FUZZ_ASSERT_THROW(cond, exc) \ - try { \ - cond; \ - FUZZ_ASSERT(false); \ - } catch (const exc&) { \ - } catch (...) { \ - FUZZ_ASSERT(false); \ - } - -enum EActionType { - AT_INSERT, - AT_CLEAR, - AT_REHASH, - AT_ATOP, - AT_AT, - AT_ITERATORS, - AT_ERASE, - AT_FIND -}; - -template <class EtalonMap, class TesteeMap, class Key, class Value> -void MakeAction(EtalonMap& etalon, TesteeMap& testee, Key&& key, Value&& value, EActionType type) { - switch (type) { - case AT_INSERT: { - auto itEt = etalon.insert({ key, value }); - if (itEt.second) { - FUZZ_ASSERT(!testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.insert(std::make_pair(key, value)); - FUZZ_ASSERT(itTs.second); - FUZZ_ASSERT(itTs.first->first == key); - FUZZ_ASSERT(itTs.first->second == value); - FUZZ_ASSERT(size + 1 == testee.size()); - FUZZ_ASSERT(bucket_count <= testee.bucket_count()); - } else { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.insert(std::make_pair(key, value)); - FUZZ_ASSERT(!itTs.second); - FUZZ_ASSERT(itTs.first->first == key); - FUZZ_ASSERT(itTs.first->second == itEt.first->second); - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - } - break; - } - case AT_CLEAR: { - auto bucket_count = testee.bucket_count(); - testee.clear(); - for (const auto& v : etalon) { - FUZZ_ASSERT(!testee.contains(v.first)); - } - FUZZ_ASSERT(testee.empty()); - FUZZ_ASSERT(testee.size() == 0); - FUZZ_ASSERT(testee.bucket_count() == bucket_count); - FUZZ_ASSERT(testee.load_factor() < std::numeric_limits<float>::epsilon()); - - etalon.clear(); - break; - } - case AT_REHASH: { - testee.rehash(key); - FUZZ_ASSERT(testee.bucket_count() >= key); - break; - } - case AT_ATOP: { - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - FUZZ_ASSERT(testee[key] == etalon[key]); - - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - } else { - FUZZ_ASSERT(!testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - FUZZ_ASSERT(testee[key] == etalon[key]); - - FUZZ_ASSERT(size + 1 == testee.size()); - FUZZ_ASSERT(bucket_count <= testee.bucket_count()); - } - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - etalon[key] = value; - testee[key] = value; - FUZZ_ASSERT(testee[key] == etalon[key]); - FUZZ_ASSERT(testee[key] == value); - - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - break; - } - case AT_AT: { - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - - FUZZ_ASSERT(testee.at(key) == etalon.at(key)); - testee.at(key) = value; - etalon.at(key) = value; - FUZZ_ASSERT(testee.at(key) == etalon.at(key)); - } else { - FUZZ_ASSERT(!testee.contains(key)); - FUZZ_ASSERT_THROW(testee.at(key) = value, std::out_of_range); - FUZZ_ASSERT(!testee.contains(key)); - } - FUZZ_ASSERT(size == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - break; - } - case AT_ITERATORS: { - auto itBeginTs = testee.begin(); - auto itEndTs = testee.end(); - FUZZ_ASSERT((size_t)std::distance(itBeginTs, itEndTs) == testee.size()); - FUZZ_ASSERT(std::distance(itBeginTs, itEndTs) == - std::distance(etalon.begin(), etalon.end())); - FUZZ_ASSERT(std::distance(testee.cbegin(), testee.cend()) == - std::distance(etalon.cbegin(), etalon.cend())); - break; - } - case AT_ERASE: { - if (etalon.contains(key)) { - FUZZ_ASSERT(testee.contains(key)); - auto size = testee.size(); - auto bucket_count = testee.bucket_count(); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs->first == key); - FUZZ_ASSERT(itTs->second == etalon.at(key)); - - testee.erase(itTs); - FUZZ_ASSERT(size - 1 == testee.size()); - FUZZ_ASSERT(bucket_count == testee.bucket_count()); - etalon.erase(key); - } else { - FUZZ_ASSERT(!testee.contains(key)); - } - break; - } - case AT_FIND: { - auto itEt = etalon.find(key); - if (itEt != etalon.end()) { - FUZZ_ASSERT(testee.contains(key)); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs != testee.end()); - FUZZ_ASSERT(itTs->first == key); - FUZZ_ASSERT(itTs->second == itEt->second); - - itTs->second = value; - itEt->second = value; - } else { - FUZZ_ASSERT(!testee.contains(key)); - - auto itTs = testee.find(key); - FUZZ_ASSERT(itTs == testee.end()); - } - break; - } - }; -} - -template <class EtalonMap, class TesteeMap> -void CheckInvariants(const EtalonMap& etalon, const TesteeMap& testee) { - using value_type = std::pair<typename TesteeMap::key_type, - typename TesteeMap::mapped_type>; - using size_type = typename TesteeMap::size_type; - - TVector<value_type> etalonVals{ etalon.begin(), etalon.end() }; - std::sort(etalonVals.begin(), etalonVals.end()); - TVector<value_type> testeeVals{ testee.begin(), testee.end() }; - std::sort(testeeVals.begin(), testeeVals.end()); - - FUZZ_ASSERT(testeeVals == etalonVals); - - FUZZ_ASSERT(testee.size() == etalon.size()); - FUZZ_ASSERT(testee.empty() == etalon.empty()); - FUZZ_ASSERT(testee.load_factor() < 0.5f + std::numeric_limits<float>::epsilon()); - FUZZ_ASSERT(testee.bucket_count() > testee.size()); - - size_type buckets = 0; - for (auto b : xrange(testee.bucket_count())) { - buckets += testee.bucket_size(b); - } - FUZZ_ASSERT(buckets == testee.size()); - - for (const auto& v : etalon) { - auto key = v.first; - auto value = v.second; - - FUZZ_ASSERT(testee.contains(key)); - FUZZ_ASSERT(testee.count(key) == 1); - - auto it = testee.find(key); - FUZZ_ASSERT(it->first == key); - FUZZ_ASSERT(it->second == value); - } -} - -} // namespace NFlatHash::NFuzz +#pragma once + +#include <util/generic/bt_exception.h> +#include <util/generic/vector.h> +#include <util/generic/xrange.h> + +#include <util/random/random.h> + +namespace NFlatHash::NFuzz { + +#define FUZZ_ASSERT(cond) \ + Y_ENSURE_EX(cond, TWithBackTrace<yexception>() << Y_STRINGIZE(cond) << " assertion failed ") + +#define FUZZ_ASSERT_THROW(cond, exc) \ + try { \ + cond; \ + FUZZ_ASSERT(false); \ + } catch (const exc&) { \ + } catch (...) { \ + FUZZ_ASSERT(false); \ + } + +enum EActionType { + AT_INSERT, + AT_CLEAR, + AT_REHASH, + AT_ATOP, + AT_AT, + AT_ITERATORS, + AT_ERASE, + AT_FIND +}; + +template <class EtalonMap, class TesteeMap, class Key, class Value> +void MakeAction(EtalonMap& etalon, TesteeMap& testee, Key&& key, Value&& value, EActionType type) { + switch (type) { + case AT_INSERT: { + auto itEt = etalon.insert({ key, value }); + if (itEt.second) { + FUZZ_ASSERT(!testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.insert(std::make_pair(key, value)); + FUZZ_ASSERT(itTs.second); + FUZZ_ASSERT(itTs.first->first == key); + FUZZ_ASSERT(itTs.first->second == value); + FUZZ_ASSERT(size + 1 == testee.size()); + FUZZ_ASSERT(bucket_count <= testee.bucket_count()); + } else { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.insert(std::make_pair(key, value)); + FUZZ_ASSERT(!itTs.second); + FUZZ_ASSERT(itTs.first->first == key); + FUZZ_ASSERT(itTs.first->second == itEt.first->second); + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + } + break; + } + case AT_CLEAR: { + auto bucket_count = testee.bucket_count(); + testee.clear(); + for (const auto& v : etalon) { + FUZZ_ASSERT(!testee.contains(v.first)); + } + FUZZ_ASSERT(testee.empty()); + FUZZ_ASSERT(testee.size() == 0); + FUZZ_ASSERT(testee.bucket_count() == bucket_count); + FUZZ_ASSERT(testee.load_factor() < std::numeric_limits<float>::epsilon()); + + etalon.clear(); + break; + } + case AT_REHASH: { + testee.rehash(key); + FUZZ_ASSERT(testee.bucket_count() >= key); + break; + } + case AT_ATOP: { + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + FUZZ_ASSERT(testee[key] == etalon[key]); + + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + } else { + FUZZ_ASSERT(!testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + FUZZ_ASSERT(testee[key] == etalon[key]); + + FUZZ_ASSERT(size + 1 == testee.size()); + FUZZ_ASSERT(bucket_count <= testee.bucket_count()); + } + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + etalon[key] = value; + testee[key] = value; + FUZZ_ASSERT(testee[key] == etalon[key]); + FUZZ_ASSERT(testee[key] == value); + + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + break; + } + case AT_AT: { + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + + FUZZ_ASSERT(testee.at(key) == etalon.at(key)); + testee.at(key) = value; + etalon.at(key) = value; + FUZZ_ASSERT(testee.at(key) == etalon.at(key)); + } else { + FUZZ_ASSERT(!testee.contains(key)); + FUZZ_ASSERT_THROW(testee.at(key) = value, std::out_of_range); + FUZZ_ASSERT(!testee.contains(key)); + } + FUZZ_ASSERT(size == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + break; + } + case AT_ITERATORS: { + auto itBeginTs = testee.begin(); + auto itEndTs = testee.end(); + FUZZ_ASSERT((size_t)std::distance(itBeginTs, itEndTs) == testee.size()); + FUZZ_ASSERT(std::distance(itBeginTs, itEndTs) == + std::distance(etalon.begin(), etalon.end())); + FUZZ_ASSERT(std::distance(testee.cbegin(), testee.cend()) == + std::distance(etalon.cbegin(), etalon.cend())); + break; + } + case AT_ERASE: { + if (etalon.contains(key)) { + FUZZ_ASSERT(testee.contains(key)); + auto size = testee.size(); + auto bucket_count = testee.bucket_count(); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs->first == key); + FUZZ_ASSERT(itTs->second == etalon.at(key)); + + testee.erase(itTs); + FUZZ_ASSERT(size - 1 == testee.size()); + FUZZ_ASSERT(bucket_count == testee.bucket_count()); + etalon.erase(key); + } else { + FUZZ_ASSERT(!testee.contains(key)); + } + break; + } + case AT_FIND: { + auto itEt = etalon.find(key); + if (itEt != etalon.end()) { + FUZZ_ASSERT(testee.contains(key)); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs != testee.end()); + FUZZ_ASSERT(itTs->first == key); + FUZZ_ASSERT(itTs->second == itEt->second); + + itTs->second = value; + itEt->second = value; + } else { + FUZZ_ASSERT(!testee.contains(key)); + + auto itTs = testee.find(key); + FUZZ_ASSERT(itTs == testee.end()); + } + break; + } + }; +} + +template <class EtalonMap, class TesteeMap> +void CheckInvariants(const EtalonMap& etalon, const TesteeMap& testee) { + using value_type = std::pair<typename TesteeMap::key_type, + typename TesteeMap::mapped_type>; + using size_type = typename TesteeMap::size_type; + + TVector<value_type> etalonVals{ etalon.begin(), etalon.end() }; + std::sort(etalonVals.begin(), etalonVals.end()); + TVector<value_type> testeeVals{ testee.begin(), testee.end() }; + std::sort(testeeVals.begin(), testeeVals.end()); + + FUZZ_ASSERT(testeeVals == etalonVals); + + FUZZ_ASSERT(testee.size() == etalon.size()); + FUZZ_ASSERT(testee.empty() == etalon.empty()); + FUZZ_ASSERT(testee.load_factor() < 0.5f + std::numeric_limits<float>::epsilon()); + FUZZ_ASSERT(testee.bucket_count() > testee.size()); + + size_type buckets = 0; + for (auto b : xrange(testee.bucket_count())) { + buckets += testee.bucket_size(b); + } + FUZZ_ASSERT(buckets == testee.size()); + + for (const auto& v : etalon) { + auto key = v.first; + auto value = v.second; + + FUZZ_ASSERT(testee.contains(key)); + FUZZ_ASSERT(testee.count(key) == 1); + + auto it = testee.find(key); + FUZZ_ASSERT(it->first == key); + FUZZ_ASSERT(it->second == value); + } +} + +} // namespace NFlatHash::NFuzz diff --git a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make index ecb590e116..78559dda57 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/fuzz_common/ya.make @@ -1,11 +1,11 @@ -LIBRARY() - -OWNER(tender-bum) - -SRCS(fuzz_common.cpp) - -PEERDIR( +LIBRARY() + +OWNER(tender-bum) + +SRCS(fuzz_common.cpp) + +PEERDIR( library/cpp/containers/flat_hash/lib -) - -END() +) + +END() diff --git a/library/cpp/containers/flat_hash/lib/fuzz/ya.make b/library/cpp/containers/flat_hash/lib/fuzz/ya.make index dbf2183be5..24b7df1a4e 100644 --- a/library/cpp/containers/flat_hash/lib/fuzz/ya.make +++ b/library/cpp/containers/flat_hash/lib/fuzz/ya.make @@ -1,7 +1,7 @@ -OWNER(tender-bum) - -RECURSE( - flat_map_fuzz - dense_map_fuzz - fuzz_common -) +OWNER(tender-bum) + +RECURSE( + flat_map_fuzz + dense_map_fuzz + fuzz_common +) |