@@ -37,21 +37,33 @@ const std::map<HistType, std::function<HistPtr(const HistogramSpec&)>> HistFacto
3737// create histogram from specification and insert it into the registry
3838void HistogramRegistry::insert (const HistogramSpec& histSpec)
3939{
40- const uint32_t i = imask (histSpec.hash );
41- for (auto j = 0u ; j < MAX_REGISTRY_SIZE; ++j) {
40+ validateHash (histSpec.hash , histSpec.name .data ());
41+ const uint32_t idx = imask (histSpec.hash );
42+ for (auto i = 0u ; i < MAX_REGISTRY_SIZE; ++i) {
4243 TObject* rawPtr = nullptr ;
43- std::visit ([&](const auto & sharedPtr) { rawPtr = sharedPtr.get (); }, mRegistryValue [imask (j + i)]);
44+ std::visit ([&](const auto & sharedPtr) { rawPtr = sharedPtr.get (); }, mRegistryValue [imask (idx + i)]);
4445 if (!rawPtr) {
4546 registerName (histSpec.name );
46- mRegistryKey [imask (j + i)] = histSpec.hash ;
47- mRegistryValue [imask (j + i)] = HistFactory::createHistVariant (histSpec);
48- lookup += j ;
47+ mRegistryKey [imask (idx + i)] = histSpec.hash ;
48+ mRegistryValue [imask (idx + i)] = HistFactory::createHistVariant (histSpec);
49+ lookup += i ;
4950 return ;
5051 }
5152 }
5253 LOGF (FATAL, R"( Internal array of HistogramRegistry "%s" is full.)" , mName );
5354}
5455
56+ void HistogramRegistry::validateHash (const uint32_t hash, const char * name)
57+ {
58+ auto it = std::find (mRegistryKey .begin (), mRegistryKey .end (), hash);
59+ if (it != mRegistryKey .end ()) {
60+ auto idx = it - mRegistryKey .begin ();
61+ std::string collidingName{};
62+ std::visit ([&](const auto & hist) { collidingName = hist->GetName (); }, mRegistryValue [idx]);
63+ LOGF (FATAL, R"( Hash collision in HistogramRegistry "%s"! Please rename histogram "%s" or "%s".)" , mName , name, collidingName);
64+ }
65+ }
66+
5567void HistogramRegistry::add (const HistogramSpec& histSpec)
5668{
5769 insert (histSpec);
@@ -201,6 +213,9 @@ void HistogramRegistry::print(bool showAxisDetails)
201213 }
202214 LOGF (INFO, " %s" , std::string (titleString.size (), ' =' ), titleString);
203215 LOGF (INFO, " Total: %d histograms, ca. %s" , nHistos, totalSizeInfo);
216+ if (lookup) {
217+ LOGF (INFO, " Due to index collisions, histograms were shifted by %d registry slots in total." , lookup);
218+ }
204219 LOGF (INFO, " %s" , std::string (titleString.size (), ' =' ), titleString);
205220 LOGF (INFO, " " );
206221}
@@ -211,9 +226,9 @@ TList* HistogramRegistry::operator*()
211226 TList* list = new TList ();
212227 list->SetName (mName .data ());
213228
214- for (auto j = 0u ; j < MAX_REGISTRY_SIZE; ++j ) {
229+ for (auto i = 0u ; i < MAX_REGISTRY_SIZE; ++i ) {
215230 TNamed* rawPtr = nullptr ;
216- std::visit ([&](const auto & sharedPtr) { rawPtr = (TNamed*)sharedPtr.get (); }, mRegistryValue [j ]);
231+ std::visit ([&](const auto & sharedPtr) { rawPtr = (TNamed*)sharedPtr.get (); }, mRegistryValue [i ]);
217232 if (rawPtr) {
218233 std::deque<std::string> path = splitPath (rawPtr->GetName ());
219234 std::string name = path.back ();
0 commit comments