File indexing completed on 2026-04-19 07:48:53
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Utilities/HashCombine.hpp"
0012
0013 #include <array>
0014 #include <cstddef>
0015 #include <cstdint>
0016 #include <unordered_set>
0017
0018 using namespace Acts;
0019
0020 namespace ActsTests {
0021
0022 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0023
0024 BOOST_AUTO_TEST_CASE(hashMix_nonIdentity) {
0025
0026
0027 for (std::size_t i = 1; i < 100; ++i) {
0028 BOOST_CHECK_NE(hashMix(i), i);
0029 }
0030 }
0031
0032 BOOST_AUTO_TEST_CASE(hashMix_distinct) {
0033
0034 std::unordered_set<std::size_t> seen;
0035 for (std::size_t i = 0; i < 10000; ++i) {
0036 auto [it, inserted] = seen.insert(hashMix(i));
0037 BOOST_CHECK(inserted);
0038 }
0039 }
0040
0041 BOOST_AUTO_TEST_CASE(hashMixAndCombine_basic) {
0042
0043 std::size_t a = hashMixAndCombine(1, 2, 3);
0044 std::size_t b = hashMixAndCombine(1, 2, 3);
0045 BOOST_CHECK_EQUAL(a, b);
0046
0047
0048 std::size_t c = hashMixAndCombine(1, 2, 4);
0049 BOOST_CHECK_NE(a, c);
0050 }
0051
0052 BOOST_AUTO_TEST_CASE(hashMixAndCombine_orderMatters) {
0053 std::size_t a = hashMixAndCombine(1, 2);
0054 std::size_t b = hashMixAndCombine(2, 1);
0055 BOOST_CHECK_NE(a, b);
0056 }
0057
0058 BOOST_AUTO_TEST_CASE(hashMixAndCombine_consecutiveCollisionRate) {
0059
0060
0061 constexpr std::size_t nBuckets = 4096;
0062
0063 std::unordered_set<std::size_t> hashes;
0064 std::array<std::size_t, nBuckets> buckets{};
0065
0066
0067
0068 std::size_t nInputs = 0;
0069 for (std::uint32_t vp = 0; vp < 10; ++vp) {
0070 for (std::uint32_t p = 0; p < 100000; ++p) {
0071 std::size_t h = hashMixAndCombine(vp, std::uint32_t{0}, p,
0072 std::uint32_t{0}, std::uint32_t{0});
0073 hashes.insert(h);
0074 buckets[h % nBuckets]++;
0075 ++nInputs;
0076 }
0077 }
0078
0079
0080 BOOST_CHECK_EQUAL(hashes.size(), nInputs);
0081
0082
0083
0084
0085 std::size_t maxBucket = *std::max_element(buckets.begin(), buckets.end());
0086 double avgBucket = static_cast<double>(nInputs) / nBuckets;
0087 double ratio = static_cast<double>(maxBucket) / avgBucket;
0088 BOOST_CHECK_LT(ratio, 2.0);
0089 }
0090
0091 BOOST_AUTO_TEST_CASE(hashMixAndCombine_multiFieldCollisionRate) {
0092
0093 std::unordered_set<std::size_t> hashes;
0094 std::size_t nInputs = 0;
0095
0096
0097 for (std::uint32_t vp = 0; vp < 20; ++vp) {
0098 for (std::uint32_t vs = 0; vs < 10; ++vs) {
0099 for (std::uint32_t p = 0; p < 500; ++p) {
0100 for (std::uint32_t g = 0; g < 5; ++g) {
0101 for (std::uint32_t sp = 0; sp < 5; ++sp) {
0102 std::size_t h = hashMixAndCombine(vp, vs, p, g, sp);
0103 hashes.insert(h);
0104 ++nInputs;
0105 }
0106 }
0107 }
0108 }
0109 }
0110
0111
0112 BOOST_CHECK_EQUAL(hashes.size(), nInputs);
0113 }
0114
0115 BOOST_AUTO_TEST_SUITE_END()
0116
0117 }