diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index bcea0a1bb7d65..2cfee5b525549 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -422,7 +422,7 @@ struct OutputObj { OutputSpec const spec() { header::DataDescription desc{}; - auto lhash = compile_time_hash(label.c_str()); + auto lhash = runtime_hash(label.c_str()); std::memset(desc.str, '_', 16); std::stringstream s; s << std::hex << lhash; diff --git a/Framework/Core/include/Framework/AnalysisManagers.h b/Framework/Core/include/Framework/AnalysisManagers.h index b447bab3e8d6c..9061ff297a924 100644 --- a/Framework/Core/include/Framework/AnalysisManagers.h +++ b/Framework/Core/include/Framework/AnalysisManagers.h @@ -188,7 +188,7 @@ template struct ConditionManager> { static bool appendCondition(std::vector& inputs, Condition& what) { - inputs.emplace_back(InputSpec{what.path, "AODC", compile_time_hash(what.path.c_str()), Lifetime::Condition, ccdbParamSpec(what.path)}); + inputs.emplace_back(InputSpec{what.path, "AODC", runtime_hash(what.path.c_str()), Lifetime::Condition, ccdbParamSpec(what.path)}); return true; } static bool newDataframe(InputRecord& inputs, Condition& what) diff --git a/Framework/Core/include/Framework/AnalysisTask.h b/Framework/Core/include/Framework/AnalysisTask.h index 0e570a49c3ccf..6cc5de92a624b 100644 --- a/Framework/Core/include/Framework/AnalysisTask.h +++ b/Framework/Core/include/Framework/AnalysisTask.h @@ -580,7 +580,7 @@ DataProcessorSpec adaptAnalysisTask(ConfigContext const& ctx, Args&&... args) } const char* name = name_str.c_str(); - auto hash = compile_time_hash(name); + auto hash = runtime_hash(name); std::vector outputs; std::vector inputs; diff --git a/Framework/Core/include/Framework/HistogramRegistry.h b/Framework/Core/include/Framework/HistogramRegistry.h index 2b128d1be91de..4b96ce75bbc98 100644 --- a/Framework/Core/include/Framework/HistogramRegistry.h +++ b/Framework/Core/include/Framework/HistogramRegistry.h @@ -175,6 +175,7 @@ class HistogramRegistry void registerName(const std::string& name); std::string mName{}; + uint32_t nameHash; OutputObjHandlingPolicy mPolicy{}; bool mCreateRegistryDir{}; bool mSortHistos{}; diff --git a/Framework/Core/include/Framework/HistogramSpec.h b/Framework/Core/include/Framework/HistogramSpec.h index d9fc32456702e..5b0c7931d1c65 100644 --- a/Framework/Core/include/Framework/HistogramSpec.h +++ b/Framework/Core/include/Framework/HistogramSpec.h @@ -182,9 +182,9 @@ struct HistogramConfigSpec { */ //************************************************************************************************** struct HistogramSpec { - HistogramSpec(char const* const name_, char const* const title_, HistogramConfigSpec config_, bool callSumw2_ = false) + HistogramSpec(char const* name_, char const* const title_, HistogramConfigSpec config_, bool callSumw2_ = false) : name(name_), - hash(compile_time_hash(name_)), + hash(runtime_hash(name_)), title(title_), config(std::move(config_)), callSumw2(callSumw2_) diff --git a/Framework/Core/include/Framework/StringHelpers.h b/Framework/Core/include/Framework/StringHelpers.h index 5eb5ce0cd88ab..2bc5e7b4a30d5 100644 --- a/Framework/Core/include/Framework/StringHelpers.h +++ b/Framework/Core/include/Framework/StringHelpers.h @@ -63,7 +63,7 @@ constexpr uint32_t crc_table[256] = {0x0L, 0x77073096L, 0xee0e612cL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL}; -constexpr uint32_t crc32(char const* str, int length) +consteval uint32_t crc32(char const* str, int length) { uint32_t crc = 0xFFFFFFFF; for (auto j = 0; j <= length; ++j) { @@ -72,13 +72,27 @@ constexpr uint32_t crc32(char const* str, int length) return crc; } -constexpr uint32_t compile_time_hash(char const* str) +consteval uint32_t compile_time_hash(char const* str) { return crc32(str, static_cast(__builtin_strlen(str)) - 1) ^ 0xFFFFFFFF; } +constexpr uint32_t runtime_crc32(char const* str, int length) +{ + uint32_t crc = 0xFFFFFFFF; + for (auto j = 0; j <= length; ++j) { + crc = (crc >> 8) ^ crc_table[(crc ^ static_cast(str[j])) & 0x000000FF]; + } + return crc; +} + +constexpr uint32_t runtime_hash(char const* str) +{ + return runtime_crc32(str, static_cast(__builtin_strlen(str)) - 1) ^ 0xFFFFFFFF; +} + template -constexpr uint32_t compile_time_hash_from_literal(const char (&str)[N]) +consteval uint32_t compile_time_hash_from_literal(const char (&str)[N]) { return crc32(str, N - 2) ^ 0xFFFFFFFF; } @@ -98,7 +112,7 @@ struct is_const_str> : std::true_type { }; template -constexpr bool is_const_str_v(T) +consteval bool is_const_str_v(T) { return is_const_str::value; } diff --git a/Framework/Core/src/CommonDataProcessors.cxx b/Framework/Core/src/CommonDataProcessors.cxx index 423627ec4f7a7..79a31af04cdcd 100644 --- a/Framework/Core/src/CommonDataProcessors.cxx +++ b/Framework/Core/src/CommonDataProcessors.cxx @@ -175,7 +175,7 @@ DataProcessorSpec CommonDataProcessors::getOutputObjHistSink(std::vectorbegin(), inputObjects->end(), [&](auto&& x) { return (x.first.uniqueId == nameHash) && (x.first.taskHash == hash); }); // If it's the first one, we just add it to the list. diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 50934bd59a729..3e944b30ed11f 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -2377,7 +2377,7 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v if (context.isSink && action.op == CompletionPolicy::CompletionOp::Consume) { O2_SIGNPOST_EVENT_EMIT(device, pcid, "device", "Sending dpl-summary"); auto& allocator = ref.get(); - allocator.make(OutputRef{"dpl-summary", compile_time_hash(spec.name.c_str())}, 1); + allocator.make(OutputRef{"dpl-summary", runtime_hash(spec.name.c_str())}, 1); } // Extra callback which allows a service to add extra outputs. diff --git a/Framework/Core/src/HistogramRegistry.cxx b/Framework/Core/src/HistogramRegistry.cxx index 25143f9c57e21..86b2e128ebb2c 100644 --- a/Framework/Core/src/HistogramRegistry.cxx +++ b/Framework/Core/src/HistogramRegistry.cxx @@ -10,22 +10,22 @@ // or submit itself to any jurisdiction. #include "Framework/HistogramRegistry.h" -#include "TClass.h" #include #include +#include namespace o2::framework { constexpr HistogramRegistry::HistName::HistName(char const* const name) : str(name), - hash(compile_time_hash(name)), + hash(runtime_hash(name)), idx(hash & REGISTRY_BITMASK) { } HistogramRegistry::HistogramRegistry(char const* const name, std::vector histSpecs, OutputObjHandlingPolicy policy, bool sortHistos, bool createRegistryDir) - : mName(name), mPolicy(policy), mRegistryKey(), mRegistryValue(), mSortHistos(sortHistos), mCreateRegistryDir(createRegistryDir) + : mName(name), mPolicy(policy), mCreateRegistryDir(createRegistryDir), mSortHistos(sortHistos), mRegistryKey(), mRegistryValue() { mRegistryKey.fill(0u); for (auto& histSpec : histSpecs) { @@ -37,7 +37,7 @@ HistogramRegistry::HistogramRegistry(char const* const name, std::vector #include #include -#include using namespace o2::framework; @@ -45,7 +44,7 @@ void loopOverMembers(TClass* cl, void* obj, auto* dm = (TDataMember*)memberlist->At(i); auto isValidComplex = [dm]() { - auto typehash = compile_time_hash(dm->GetTypeName()); + auto typehash = runtime_hash(dm->GetTypeName()); return isString(*dm) || dm->IsEnum() || dm->IsSTLContainer() || (typehash == compile_time_hash("o2::framework::Array2D")) || (typehash == compile_time_hash("o2::framework::Array2D")) || @@ -93,7 +92,7 @@ void ptreeToMember(boost::property_tree::ptree const& value, TDataMember* dm, void* ptr) { - auto typehash = compile_time_hash(dm->GetTypeName()); + auto typehash = runtime_hash(dm->GetTypeName()); if (dm->IsSTLContainer()) { switch (typehash) { case compile_time_hash("vector"): @@ -198,7 +197,7 @@ void ptreeToMember(boost::property_tree::ptree const& value, // Convert a DataMember to a ConfigParamSpec ConfigParamSpec memberToConfigParamSpec(const char* tname, TDataMember* dm, void* ptr) { - auto typehash = compile_time_hash(dm->GetTypeName()); + auto typehash = runtime_hash(dm->GetTypeName()); if (dm->IsSTLContainer()) { switch (typehash) { case compile_time_hash("vector"): diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 6b4ad35f826be..f5a66722aa713 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -337,12 +337,12 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext for (size_t wi = 0; wi < workflow.size(); ++wi) { auto& processor = workflow[wi]; auto name = processor.name; - auto hash = compile_time_hash(name.c_str()); + auto hash = runtime_hash(name.c_str()); outTskMap.push_back({hash, name}); std::string prefix = "internal-dpl-"; if (processor.inputs.empty() && processor.name.compare(0, prefix.size(), prefix) != 0) { - processor.inputs.push_back(InputSpec{"enumeration", "DPL", "ENUM", static_cast(compile_time_hash(processor.name.c_str())), Lifetime::Enumeration}); + processor.inputs.push_back(InputSpec{"enumeration", "DPL", "ENUM", static_cast(runtime_hash(processor.name.c_str())), Lifetime::Enumeration}); ConfigParamsHelper::addOptionIfMissing(processor.options, ConfigParamSpec{"orbit-offset-enumeration", VariantType::Int64, 0ll, {"1st injected orbit"}}); ConfigParamsHelper::addOptionIfMissing(processor.options, ConfigParamSpec{"orbit-multiplier-enumeration", VariantType::Int64, 0ll, {"orbits/TForbit"}}); processor.options.push_back(ConfigParamSpec{"start-value-enumeration", VariantType::Int64, 0ll, {"initial value for the enumeration"}}); @@ -368,7 +368,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext bool timeframeSink = hasTimeframeInputs && !hasTimeframeOutputs; if (std::stoi(ctx.options().get("timeframes-rate-limit-ipcid")) != -1) { if (timeframeSink && processor.name != "internal-dpl-injected-dummy-sink") { - processor.outputs.push_back(OutputSpec{{"dpl-summary"}, ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(compile_time_hash(processor.name.c_str()))}}); + processor.outputs.push_back(OutputSpec{{"dpl-summary"}, ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(runtime_hash(processor.name.c_str()))}}); } } bool hasConditionOption = false; diff --git a/Framework/Core/test/test_StringHelpers.cxx b/Framework/Core/test/test_StringHelpers.cxx index 7f06c9bc4e367..4d3f43f0a845d 100644 --- a/Framework/Core/test/test_StringHelpers.cxx +++ b/Framework/Core/test/test_StringHelpers.cxx @@ -16,9 +16,9 @@ TEST_CASE("StringHelpersHash") { std::string s{"test-string"}; char const* const cs = "test-string"; - REQUIRE(compile_time_hash(s.c_str()) == compile_time_hash("test-string")); - REQUIRE(compile_time_hash(cs) == compile_time_hash("test-string")); - REQUIRE(compile_time_hash(s.c_str()) == compile_time_hash(cs)); + REQUIRE(runtime_hash(s.c_str()) == compile_time_hash("test-string")); + REQUIRE(runtime_hash(cs) == compile_time_hash("test-string")); + REQUIRE(runtime_hash(s.c_str()) == runtime_hash(cs)); } template