From 189e551dc716d0f7355d02f8ba59334fc8ad05f3 Mon Sep 17 00:00:00 2001 From: Christian Mazakas <5543573+cmazakas@users.noreply.github.com> Date: Tue, 1 Nov 2022 09:05:18 -0700 Subject: [PATCH] Add test proving `max_load()` invariants (#156) --- test/Jamfile.v2 | 1 + test/helpers/fwd.hpp | 3 +- test/helpers/generators.hpp | 12 +++++ test/unordered/max_load_tests.cpp | 77 +++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/unordered/max_load_tests.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6a9d4684..c3284098 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -138,6 +138,7 @@ build_foa contains_tests ; build_foa erase_if ; build_foa scary_tests ; build_foa init_type_insert_tests ; +build_foa max_load_tests ; run unordered/hash_is_avalanching_test.cpp ; diff --git a/test/helpers/fwd.hpp b/test/helpers/fwd.hpp index a5657e01..a1a7cda4 100644 --- a/test/helpers/fwd.hpp +++ b/test/helpers/fwd.hpp @@ -12,7 +12,8 @@ namespace test { typedef enum { default_generator, generate_collisions, - limited_range + limited_range, + sequential } random_generator; int generate(int const*, random_generator); diff --git a/test/helpers/generators.hpp b/test/helpers/generators.hpp index c9ed42bd..084184e0 100644 --- a/test/helpers/generators.hpp +++ b/test/helpers/generators.hpp @@ -12,7 +12,9 @@ #define BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER #include "./fwd.hpp" +#include #include +#include #include #include #include @@ -34,8 +36,18 @@ namespace test { return static_cast(rand()) % max; } + static int origin = 0; + + void reset_sequence() { origin = 0; } + inline int generate(int const*, random_generator g) { + if (g == sequential) { + BOOST_ASSERT( + g + 1 < INT_MAX && "test::reset_sequence() should be invoked"); + return origin++; + } + using namespace std; int value = rand(); if (g == limited_range) { diff --git a/test/unordered/max_load_tests.cpp b/test/unordered/max_load_tests.cpp new file mode 100644 index 00000000..dc117177 --- /dev/null +++ b/test/unordered/max_load_tests.cpp @@ -0,0 +1,77 @@ +#if !defined(BOOST_UNORDERED_FOA_TESTS) +#error "max_load_tests is currently only supported by open-addressed containers" +#else + +#include "../helpers/unordered.hpp" + +#include "../helpers/helpers.hpp" +#include "../helpers/random_values.hpp" +#include "../helpers/test.hpp" +#include "../helpers/tracker.hpp" +#include "../objects/test.hpp" + +template void max_load_tests(X*, test::random_generator generator) +{ + typedef typename X::size_type size_type; + + test::reset_sequence(); + + X x; + size_type max_load = x.max_load(); + + BOOST_TEST_EQ(max_load, 0u); + + x.reserve(1000); + max_load = x.max_load(); + + size_type bucket_count = x.bucket_count(); + BOOST_TEST_GE(bucket_count, 1000u); + + test::ordered tracker; + { + test::random_values v(max_load, generator); + + x.insert(v.begin(), v.end()); + tracker.insert_range(v.begin(), v.end()); + + BOOST_TEST_EQ(x.bucket_count(), bucket_count); + BOOST_TEST_EQ(x.max_load(), max_load); + BOOST_TEST_EQ(x.size(), max_load); + } + + { + test::random_values v(100, generator); + + x.insert(v.begin(), v.end()); + tracker.insert_range(v.begin(), v.end()); + + BOOST_TEST_GT(x.bucket_count(), bucket_count); + BOOST_TEST_GT(x.max_load(), max_load); + BOOST_TEST_GT(x.size(), max_load); + } + + tracker.compare(x); +} + +using test::default_generator; +using test::generate_collisions; +using test::limited_range; +using test::sequential; + +boost::unordered_flat_set* int_set_ptr; +boost::unordered_flat_map >* test_map_ptr; + +boost::unordered_flat_set >* test_set_tracking; +boost::unordered_flat_map > >* + test_map_tracking; + +UNORDERED_TEST(max_load_tests, + ((int_set_ptr)(test_map_ptr)(test_set_tracking)(test_map_tracking))( + (sequential))) +#endif + +RUN_TESTS()