11#ifndef O2_FRAMEWORK_INPUTRECORD_H_
12#define O2_FRAMEWORK_INPUTRECORD_H_
40#include <fairmq/FwdDecls.h>
137 template <
typename T>
147 using base = std::default_delete<T>;
162 mProperty =
other.mProperty;
163 }
else if (mProperty !=
other.mProperty) {
177 base::operator=(
other);
179 mProperty =
other.mProperty;
180 }
else if (mProperty !=
other.mProperty) {
192 base::operator()(
ptr);
204 [[nodiscard]]
int getPos(
const std::string&
name)
const;
230 auto msg = describeAvailableInputs();
231 throw runtime_error_f(
"InputRecord::get: no input with binding %s found. %s", bindingName,
msg.c_str());
236 template <
typename R>
237 requires std::is_convertible_v<R, char const*>
243 template <
typename R>
244 requires requires(
R r) {
r.c_str(); }
250 template <
typename R>
251 requires std::is_convertible_v<R, DataRef>
268 template <
typename T = DataRef,
typename R>
273 using PointerLessValueT = std::remove_pointer_t<T>;
275 if constexpr (std::is_same_v<std::decay_t<T>,
DataRef>) {
277 }
else if constexpr (std::is_same<T, std::string>::value) {
286 }
else if constexpr (std::is_same<T, char const*>::value) {
293 return reinterpret_cast<char const*
>(
ref.payload);
296 }
else if constexpr (std::is_same<T, TableConsumer>::value) {
300 auto data =
reinterpret_cast<uint8_t const*
>(
ref.payload);
307 static_assert(is_messageable<typename T::value_type>::value,
"span can only be created for messageable types");
308 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
311 throw runtime_error(
"Inconsistent serialization method for extracting span");
313 using ValueT =
typename T::value_type;
315 if (payloadSize %
sizeof(ValueT)) {
321 return gsl::span<ValueT const>(
reinterpret_cast<ValueT const*
>(
ref.payload), payloadSize /
sizeof(ValueT));
326 if constexpr (is_specialization_v<std::remove_const_t<T>, std::vector>) {
327 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
329 auto method = header->payloadSerializationMethod;
333 auto*
start =
reinterpret_cast<typename T::value_type const*
>(
ref.payload);
334 auto*
end =
start + payloadSize /
sizeof(
typename T::value_type);
343 using NonConstT =
typename std::remove_const<T>::type;
347 auto object = DataRefUtils::as<NonConstT>(
ref);
351 std::swap(
const_cast<NonConstT&
>(container), *
object);
354 throw runtime_error(
"No supported conversion function for ROOT serialized message");
357 throw runtime_error(
"Attempt to extract object from message with unsupported serialization type");
360 static_assert(always_static_assert_v<T>,
"unsupported code path");
364 }
else if constexpr (is_messageable<T>::value) {
370 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
371 auto method = header->payloadSerializationMethod;
375 throw runtime_error(
"Can not extract a plain object from serialized message");
377 return *
reinterpret_cast<T const*
>(
ref.payload);
380 }
else if constexpr (std::is_pointer_v<T> &&
381 (is_messageable<PointerLessValueT>::value ||
387 using ValueT = PointerLessValueT;
389 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
391 auto method = header->payloadSerializationMethod;
393 if constexpr (is_messageable<ValueT>::value) {
394 auto const*
ptr =
reinterpret_cast<ValueT const*
>(
ref.payload);
401 auto*
start =
reinterpret_cast<typename ValueT::value_type const*
>(
ref.payload);
402 auto*
end =
start + payloadSize /
sizeof(
typename ValueT::value_type);
403 auto container = std::make_unique<ValueT>(
start,
end);
426 ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification};
433 auto cacheEntry = cache.matcherToEntry.find(
path);
434 if (cacheEntry == cache.matcherToEntry.end()) {
436 void* obj = (
void*)
result.get();
439 LOGP(info,
"Caching in {} ptr to {} ({})",
id.
value,
path, obj);
442 auto&
entry = cacheEntry->second;
444 if (
entry.id.value ==
id.value) {
445 std::unique_ptr<ValueT const, Deleter<ValueT const>>
result((ValueT
const*)
entry.obj,
false);
450 delete reinterpret_cast<ValueT*
>(
entry.obj);
452 void* obj = (
void*)
result.get();
454 LOGP(info,
"Replacing cached entry {} with {} for {} ({})",
entry.id.value,
id.value,
path, obj);
459 throw runtime_error(
"Attempt to extract object from message with unsupported serialization type");
461 }
else if constexpr (std::is_pointer_v<T>) {
467 static_assert(always_static_assert_v<T>,
"ROOT objects need to be retrieved by pointer");
471 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
472 auto method = header->payloadSerializationMethod;
476 "Type mismatch: attempt to extract a non-messagable object "
477 "from message with unserialized data");
485 throw runtime_error(
"Attempt to extract object from message with unsupported serialization type");
490 template <
typename T = DataRef,
typename R>
491 std::map<std::string, std::string>&
get(
R binding,
int part = 0) const
495 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
497 auto method = header->payloadSerializationMethod;
499 throw runtime_error(
"Attempt to extract metadata from a non-CCDB serialised message");
506 ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification};
513 auto [it, inserted] = cache.matcherToMetadata.emplace(
515 LOGP(info,
"Caching CCDB metadata {}: {}",
id.
value,
path);
516 return it->second.metadata;
518 auto&
entry = cacheEntry->second;
520 if (
entry.id.value ==
id.value) {
521 LOGP(
debug,
"Returning cached CCDB metatada {}: {}",
id.
value,
path);
522 return entry.metadata;
525 LOGP(info,
"Replacing cached entry {} with {} for {}",
entry.id.value,
id.value,
path);
528 return entry.metadata;
531 template <
typename T = DataRef,
typename R>
536 auto header = DataRefUtils::getHeader<header::DataHeader*>(
ref);
538 throw runtime_error(
"Attempt to extract CCDBBlob from a non-CCDB-serialized message");
543 template <
typename T>
544 requires(std::same_as<T, DataRef>)
549 auto msg = describeAvailableInputs();
555 template <
typename T>
556 requires(std::same_as<T, TableConsumer>)
559 auto ref = get<DataRef>(matcher, part);
560 auto data =
reinterpret_cast<uint8_t const*
>(
ref.payload);
565 [[nodiscard]]
bool isValid(std::string
const& s)
const
571 bool isValid(
char const* s)
const;
577 [[nodiscard]]
size_t size()
const;
584 template <
typename ParentT,
typename T>
602 if (mPosition < mSize) {
603 if (mParent->isValid(mPosition)) {
604 mElement = mParent->getByPos(mPosition);
616 while (mPosition < mSize && ++mPosition < mSize) {
617 if (!mParent->isValid(mPosition)) {
620 mElement = mParent->getByPos(mPosition);
623 if (mPosition >= mSize) {
644 return mPosition == rh.mPosition;
649 return mPosition != rh.mPosition;
654 if (mPosition >= mSize || mElement.header ==
nullptr) {
659 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(mElement);
660 return *dh == matcher;
665 if (mPosition >= mSize || mElement.header ==
nullptr) {
670 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(mElement);
691 return mParent->parts(mPosition);
704 template <
typename T>
735 return {
this,
false};
769 [[nodiscard]] std::string describeAvailableInputs()
const;
772 std::vector<InputRoute>
const& mInputsSchema;
header::DataOrigin origin
header::DataDescription description
std::vector< OutputRoute > routes
GLuint const GLchar * name
GLsizei const GLfloat * value
GLsizei GLenum const void * indices
GLsizei const GLchar *const * path
constexpr o2::header::DataDescription gDataDescriptionInvalid
Defining ITS Vertex explicitly as messageable.
RuntimeErrorRef runtime_error(const char *)
RuntimeErrorRef runtime_error_f(const char *,...)
std::string to_string(gsl::span< T, Size > span)
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
static std::map< std::string, std::string > extractCCDBHeaders(DataRef const &ref)
static std::span< const char > getCCDBPayloadBlob(DataRef const &ref)
static auto as(DataRef const &ref)
static std::string describe(InputSpec const &spec)
Per-path cache entry for a deserialised CCDB object.
static Id fromRef(DataRef &ref)
Per-path cache entry for the CCDB metadata map.
std::unordered_map< std::string, Entry > matcherToEntry
std::unordered_map< std::string, MetadataEntry > matcherToMetadata
VectorOfTObjectPtrs other
uint64_t const void const *restrict const msg