From c7de0387e52bf2f3ce73819a1f3368c8c9427995 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 1 Apr 2026 15:15:12 +0200 Subject: [PATCH] DPL: add ability to get CCDB blobs without deserialization --- .../Core/include/Framework/DataRefUtils.h | 5 +++++ .../Core/include/Framework/InputRecord.h | 19 +++++++++++++++++++ Framework/Core/src/DataRefUtils.cxx | 16 ++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/Framework/Core/include/Framework/DataRefUtils.h b/Framework/Core/include/Framework/DataRefUtils.h index d50699badc63b..498b4eb5f7a87 100644 --- a/Framework/Core/include/Framework/DataRefUtils.h +++ b/Framework/Core/include/Framework/DataRefUtils.h @@ -23,6 +23,7 @@ #include +#include #include #include @@ -184,6 +185,10 @@ struct DataRefUtils { // Decode a CCDB object using the CcdbApi. static void* decodeCCDB(DataRef const& ref, std::type_info const& info); static std::map extractCCDBHeaders(DataRef const& ref); + /// Return a span over the raw CCDB payload bytes, stripping the flattened HTTP + /// headers footer that CCDBFetcherHelper appends. Use this when the CCDB entry is + /// a binary blob rather than a ROOT-serialised object. + static std::span getCCDBPayloadBlob(DataRef const& ref); static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef& ref) { diff --git a/Framework/Core/include/Framework/InputRecord.h b/Framework/Core/include/Framework/InputRecord.h index 96963f88524be..5e8b4a256703a 100644 --- a/Framework/Core/include/Framework/InputRecord.h +++ b/Framework/Core/include/Framework/InputRecord.h @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -44,6 +45,12 @@ namespace o2::framework struct CCDBMetadataExtractor { }; +/// Tag type to retrieve the raw binary payload of a CCDB entry without ROOT +/// deserialization. The returned span is valid for the duration of the +/// processing callback. Use as: inputs.get("binding") +struct CCDBBlob { +}; + struct InputSpec; class InputSpan; class CallbackService; @@ -512,6 +519,18 @@ class InputRecord return cache.idToMetadata[id]; } + template + std::span get(R binding, int part = 0) const + requires std::same_as + { + auto ref = getRef(binding, part); + auto header = DataRefUtils::getHeader(ref); + if (header->payloadSerializationMethod != header::gSerializationMethodCCDB) { + throw runtime_error("Attempt to extract CCDBBlob from a non-CCDB-serialized message"); + } + return DataRefUtils::getCCDBPayloadBlob(ref); + } + template requires(std::same_as) decltype(auto) get(ConcreteDataMatcher matcher, int part = 0) diff --git a/Framework/Core/src/DataRefUtils.cxx b/Framework/Core/src/DataRefUtils.cxx index 69eb1dc7faba6..894ad0b8ace63 100644 --- a/Framework/Core/src/DataRefUtils.cxx +++ b/Framework/Core/src/DataRefUtils.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include #include #include #include "Framework/DataRefUtils.h" @@ -148,4 +149,19 @@ std::map DataRefUtils::extractCCDBHeaders(DataRef cons return res; } +std::span DataRefUtils::getCCDBPayloadBlob(DataRef const& ref) +{ + auto* dh = o2::header::get(ref.header); + const char* buff = ref.payload; + size_t payloadSize = dh->payloadSize; + constexpr char FlatHeaderAnnot[] = "$HEADER$"; + constexpr size_t Offset = sizeof(int) + sizeof(FlatHeaderAnnot); + int headerSize = 0; + if (payloadSize >= Offset && + !std::strncmp(buff + payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) { + headerSize = *reinterpret_cast(buff + payloadSize - Offset); + } + return {buff, payloadSize - headerSize}; +} + } // namespace o2::framework