From cd1ea288df8a3e691940681bd3614c59e350f4ae Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sun, 26 Apr 2026 10:00:31 +0200 Subject: [PATCH] indexed_hash fixes and small speedup --- src/common.h | 18 +++++++++--------- src/indexed_hash.cpp | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/common.h b/src/common.h index 4954a28..29851cd 100644 --- a/src/common.h +++ b/src/common.h @@ -162,9 +162,9 @@ struct alignas(uint64_t) hash { uint8_t h[HASH_SIZE]; - FORCEINLINE constexpr hash() : h{} {} + FORCEINLINE constexpr hash() noexcept : h{} {} - constexpr hash(std::initializer_list l) : h{} { + constexpr hash(std::initializer_list l) noexcept : h{} { auto it = l.begin(); for (size_t i = 0; (i < HASH_SIZE) && (it != l.end()); ++i, ++it) { @@ -172,7 +172,7 @@ struct alignas(uint64_t) hash } } - explicit constexpr hash(const char (&s)[HASH_SIZE * 2 + 1]) : h{} { + explicit constexpr hash(const char (&s)[HASH_SIZE * 2 + 1]) noexcept : h{} { for (size_t i = 0; i < HASH_SIZE * 2; ++i) { char c = s[i]; @@ -417,18 +417,18 @@ struct indexed_hash BUCKET_SHIFT = 32 - BUCKET_BITS, }; - static_assert((BUCKET_BITS > 0) && (BUCKET_BITS < 32), "Invalid bucket bit size"); + static_assert((BUCKET_BITS > 0) && (BUCKET_BITS < 32) && (BUCKET_BITS + BUCKET_SHIFT == 32), "Invalid bucket bit size"); - FORCEINLINE indexed_hash() : m_index(std::numeric_limits::max()) {} + FORCEINLINE indexed_hash() noexcept : m_index(std::numeric_limits::max()) {} explicit indexed_hash(const hash& h); ~indexed_hash(); - indexed_hash(const indexed_hash& h); - FORCEINLINE indexed_hash(indexed_hash&& h) : m_index(h.m_index) { h.m_index = std::numeric_limits::max(); } + indexed_hash(const indexed_hash& h) noexcept; + FORCEINLINE indexed_hash(indexed_hash&& h) noexcept : m_index(h.m_index) { h.m_index = std::numeric_limits::max(); } - indexed_hash& operator=(const indexed_hash& h); - indexed_hash& operator=(indexed_hash&& h); + indexed_hash& operator=(const indexed_hash& h) noexcept; + indexed_hash& operator=(indexed_hash&& h) noexcept; FORCEINLINE indexed_hash& operator=(const hash& h) { diff --git a/src/indexed_hash.cpp b/src/indexed_hash.cpp index b103714..59932ae 100644 --- a/src/indexed_hash.cpp +++ b/src/indexed_hash.cpp @@ -119,15 +119,17 @@ indexed_hash::indexed_hash(const hash& h) p2.second = 1; } else { - if (n > INDEX_MASK) { + const uint32_t index = (bucket << BUCKET_SHIFT) | n; + + if ((n > INDEX_MASK) || (index == std::numeric_limits::max())) { LOGERR(0, "fatal error: storage overflow"); PANIC_STOP(); } - m_index = (bucket << BUCKET_SHIFT) | n; + m_index = index; if (n == d1.capacity()) { - const uint32_t new_capacity = static_cast(std::min(n + ((n + 3) / 4), INDEX_MASK + 1)); + const uint32_t new_capacity = static_cast(std::min(n + (n / 4) + 1, INDEX_MASK + 1)); d1.reserve(new_capacity); d2.reserve(new_capacity); } @@ -142,7 +144,7 @@ indexed_hash::~indexed_hash() decref(m_index); } -indexed_hash::indexed_hash(const indexed_hash& h) +indexed_hash::indexed_hash(const indexed_hash& h) noexcept { const uint32_t i = h.m_index; @@ -150,7 +152,7 @@ indexed_hash::indexed_hash(const indexed_hash& h) incref(i); } -indexed_hash& indexed_hash::operator=(const indexed_hash& h) +indexed_hash& indexed_hash::operator=(const indexed_hash& h) noexcept { if (this == &h) { return *this; @@ -171,7 +173,7 @@ indexed_hash& indexed_hash::operator=(const indexed_hash& h) return *this; } -indexed_hash& indexed_hash::operator=(indexed_hash&& h) +indexed_hash& indexed_hash::operator=(indexed_hash&& h) noexcept { if (this == &h) { return *this; @@ -219,6 +221,13 @@ hash indexed_hash::get(uint32_t index) bool indexed_hash::is_same(uint32_t index, uint32_t bucket, const hash& h) { +#ifdef P2POOL_DEBUGGING + if ((index >> BUCKET_SHIFT) != bucket) { + LOGERR(0, "fatal error: bucket doesn't match index"); + PANIC_STOP(); + } +#endif + const auto& d1 = storage1[bucket]; index &= INDEX_MASK;