#include "config.h"
#include "HashTable.h"
#include "DataLog.h"
#include <mutex>
namespace WTF {
#if DUMP_HASHTABLE_STATS
std::atomic<unsigned> HashTableStats::numAccesses;
std::atomic<unsigned> HashTableStats::numRehashes;
std::atomic<unsigned> HashTableStats::numRemoves;
std::atomic<unsigned> HashTableStats::numReinserts;
unsigned HashTableStats::numCollisions;
unsigned HashTableStats::collisionGraph[4096];
unsigned HashTableStats::maxCollisions;
static std::mutex& hashTableStatsMutex()
{
static std::once_flag onceFlag;
static std::mutex* mutex;
std::call_once(onceFlag, []{
mutex = std::make_unique<std::mutex>().release();
});
return *mutex;
}
void HashTableStats::recordCollisionAtCount(unsigned count)
{
std::lock_guard<std::mutex> lock(hashTableStatsMutex());
if (count > maxCollisions)
maxCollisions = count;
numCollisions++;
collisionGraph[count]++;
}
void HashTableStats::dumpStats()
{
std::lock_guard<std::mutex> lock(hashTableStatsMutex());
dataLogF("\nWTF::HashTable statistics\n\n");
dataLogF("%u accesses\n", numAccesses.load());
dataLogF("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses);
dataLogF("longest collision chain: %d\n", maxCollisions);
for (unsigned i = 1; i <= maxCollisions; i++) {
dataLogF(" %u lookups with exactly %u collisions (%.2f%% , %.2f%% with this many or more)\n", collisionGraph[i], i, 100.0 * (collisionGraph[i] - collisionGraph[i+1]) / numAccesses, 100.0 * collisionGraph[i] / numAccesses);
}
dataLogF("%d rehashes\n", numRehashes.load());
dataLogF("%d reinserts\n", numReinserts.load());
}
#endif
}