Skip to content

Instantly share code, notes, and snippets.

@l0rinc
Created May 4, 2026 13:30
Show Gist options
  • Select an option

  • Save l0rinc/d68f56c3ed89f76f56da6632ef6f2d92 to your computer and use it in GitHub Desktop.

Select an option

Save l0rinc/d68f56c3ed89f76f56da6632ef6f2d92 to your computer and use it in GitHub Desktop.
commit c978cc44712cc3637d961981a5c9f8932c9d42a6
Author: Lőrinc <pap.lorinc@gmail.com>
Date: Thu Apr 30 13:47:56 2026 +0200
temp: log CCoinsMap bucket distribution
Log CCoinsMap bucket counts before cache flush and sync operations.
This temporary measurement commit records size, bucket count, load factor, maximum bucket size, and bucket-size histogram bins for comparing outpoint hashers during reindex-chainstate.
diff --git a/src/coins.cpp b/src/coins.cpp
index c403e006c8..717ae03127 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -10,10 +10,53 @@
#include <util/log.h>
#include <util/trace.h>
+#include <array>
+
TRACEPOINT_SEMAPHORE(utxocache, add);
TRACEPOINT_SEMAPHORE(utxocache, spent);
TRACEPOINT_SEMAPHORE(utxocache, uncache);
+namespace {
+
+void LogCoinsMapBucketDistribution(const CCoinsMap& map, const char* context)
+{
+ if (map.empty()) return;
+
+ std::array<size_t, 8> buckets{};
+ size_t max_bucket_size{0};
+ for (size_t bucket{0}; bucket < map.bucket_count(); ++bucket) {
+ const size_t bucket_size{map.bucket_size(bucket)};
+ if (bucket_size > max_bucket_size) max_bucket_size = bucket_size;
+
+ if (bucket_size <= 4) {
+ ++buckets[bucket_size];
+ } else if (bucket_size <= 8) {
+ ++buckets[5];
+ } else if (bucket_size <= 16) {
+ ++buckets[6];
+ } else {
+ ++buckets[7];
+ }
+ }
+
+ LogInfo("CCoinsMap bucket distribution (%s): size=%zu bucket_count=%zu load_factor=%.6f max_bucket_size=%zu buckets{0=%zu,1=%zu,2=%zu,3=%zu,4=%zu,5-8=%zu,9-16=%zu,17+=%zu}",
+ context,
+ map.size(),
+ map.bucket_count(),
+ static_cast<double>(map.load_factor()),
+ max_bucket_size,
+ buckets[0],
+ buckets[1],
+ buckets[2],
+ buckets[3],
+ buckets[4],
+ buckets[5],
+ buckets[6],
+ buckets[7]);
+}
+
+} // namespace
+
CoinsViewEmpty& CoinsViewEmpty::Get()
{
static CoinsViewEmpty instance;
@@ -259,6 +302,7 @@ void CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256& in
void CCoinsViewCache::Flush(bool reallocate_cache)
{
+ LogCoinsMapBucketDistribution(cacheCoins, reallocate_cache ? "Flush reallocate=true" : "Flush reallocate=false");
auto cursor{CoinsViewCacheCursor(m_dirty_count, m_sentinel, cacheCoins, /*will_erase=*/true)};
base->BatchWrite(cursor, m_block_hash);
Assume(m_dirty_count == 0);
@@ -271,6 +315,7 @@ void CCoinsViewCache::Flush(bool reallocate_cache)
void CCoinsViewCache::Sync()
{
+ LogCoinsMapBucketDistribution(cacheCoins, "Sync");
auto cursor{CoinsViewCacheCursor(m_dirty_count, m_sentinel, cacheCoins, /*will_erase=*/false)};
base->BatchWrite(cursor, m_block_hash);
Assume(m_dirty_count == 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment