|
40 | 40 | namespace o2::framework |
41 | 41 | { |
42 | 42 |
|
| 43 | +// Wrapper class to get CCDB metadata |
| 44 | +struct CCDBMetadataExtractor { |
| 45 | +}; |
| 46 | + |
43 | 47 | struct InputSpec; |
44 | 48 | class InputSpan; |
45 | 49 | class CallbackService; |
@@ -464,6 +468,49 @@ class InputRecord |
464 | 468 | } |
465 | 469 | } |
466 | 470 |
|
| 471 | + template <typename T = DataRef, typename R> |
| 472 | + std::map<std::string, std::string>& get(R binding, int part = 0) const |
| 473 | + requires std::same_as<T, CCDBMetadataExtractor> |
| 474 | + { |
| 475 | + auto ref = getRef(binding, part); |
| 476 | + auto header = DataRefUtils::getHeader<header::DataHeader*>(ref); |
| 477 | + auto payloadSize = DataRefUtils::getPayloadSize(ref); |
| 478 | + auto method = header->payloadSerializationMethod; |
| 479 | + if (method != header::gSerializationMethodCCDB) { |
| 480 | + throw runtime_error("Attempt to extract metadata from a non-CCDB serialised message"); |
| 481 | + } |
| 482 | + // This is to support deserialising objects from CCDB. Contrary to what happens for |
| 483 | + // other objects, those objects are most likely long lived, so we |
| 484 | + // keep around an instance of the associated object and deserialise it only when |
| 485 | + // it's updated. |
| 486 | + auto id = ObjectCache::Id::fromRef(ref); |
| 487 | + ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification}; |
| 488 | + // If the matcher does not have an entry in the cache, deserialise it |
| 489 | + // and cache the deserialised object at the given id. |
| 490 | + auto path = fmt::format("{}", DataSpecUtils::describe(matcher)); |
| 491 | + LOGP(debug, "{}", path); |
| 492 | + auto& cache = mRegistry.get<ObjectCache>(); |
| 493 | + auto cacheEntry = cache.matcherToMetadataId.find(path); |
| 494 | + if (cacheEntry == cache.matcherToMetadataId.end()) { |
| 495 | + cache.matcherToMetadataId.insert(std::make_pair(path, id)); |
| 496 | + cache.idToMetadata[id] = extractCCDBHeaders(ref); |
| 497 | + LOGP(info, "Caching CCDB metadata {}: {}", id.value, path); |
| 498 | + return cache.idToMetadata[id]; |
| 499 | + } |
| 500 | + auto& oldId = cacheEntry->second; |
| 501 | + // The id in the cache is the same, let's simply return it. |
| 502 | + if (oldId.value == id.value) { |
| 503 | + LOGP(debug, "Returning cached CCDB metatada {}: {}", id.value, path); |
| 504 | + return cache.idToMetadata[id]; |
| 505 | + } |
| 506 | + // The id in the cache is different. Let's destroy the old cached entry |
| 507 | + // and create a new one. |
| 508 | + LOGP(info, "Replacing cached entry {} with {} for {}", oldId.value, id.value, path); |
| 509 | + cache.idToObject[id] = extracCCDBMetadata(ref); |
| 510 | + oldId.value = id.value; |
| 511 | + return cache.idToObject[id]; |
| 512 | + } |
| 513 | + |
467 | 514 | /// Helper method to be used to check if a given part of the InputRecord is present. |
468 | 515 | [[nodiscard]] bool isValid(std::string const& s) const |
469 | 516 | { |
|
0 commit comments