Skip to content

Commit d548c13

Browse files
committed
DPL: replace/return desirialized CCDB objects based on etag comparison
1 parent 3eec9b6 commit d548c13

2 files changed

Lines changed: 30 additions & 16 deletions

File tree

Framework/Core/include/Framework/InputRecord.h

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ class InputRecord
413413
// it's updated.
414414
// FIXME: add ability to apply callbacks to deserialised objects.
415415
auto id = ObjectCache::Id::fromRef(ref);
416+
auto metadata = DataRefUtils::extractCCDBHeaders(ref);
417+
id.etag = metadata.count("ETag") ? metadata.at("ETag") : "";
416418
ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification};
417419
// If the matcher does not have an entry in the cache, deserialise it
418420
// and cache the deserialised object at the given id.
@@ -427,25 +429,29 @@ class InputRecord
427429
void* obj = (void*)result.get();
428430
callbacks.call<CallbackService::Id::CCDBDeserialised>((ConcreteDataMatcher&)matcher, (void*)obj);
429431
cache.idToObject[id] = obj;
430-
LOGP(info, "Caching in {} ptr to {} ({})", id.value, path, obj);
432+
LOGP(info, "Caching in {} ptr ({}) to {} ({})", id.value, id.etag.data(), path, obj);
431433
return result;
432434
}
433435
auto& oldId = cacheEntry->second;
434436
// The id in the cache is the same, let's simply return it.
435-
if (oldId.value == id.value) {
436-
std::unique_ptr<ValueT const, Deleter<ValueT const>> result((ValueT const*)cache.idToObject[id], false);
437-
LOGP(debug, "Returning cached entry {} for {} ({})", id.value, path, (void*)result.get());
437+
// If the etag is present in both, we compare etags, otherwise we compare values
438+
if (oldId == id) {
439+
std::unique_ptr<ValueT const, Deleter<ValueT const>> result((ValueT const*)cache.idToObject[oldId], false);
440+
LOGP(debug, "Returning cached entry {} ({}) for {} ({})", oldId.value, oldId.etag.data(), path, (void*)result.get());
438441
return result;
439442
}
440443
// The id in the cache is different. Let's destroy the old cached entry
441444
// and create a new one.
442-
delete reinterpret_cast<ValueT*>(cache.idToObject[oldId]);
445+
if constexpr (!std::is_base_of<o2::conf::ConfigurableParam, ValueT>::value) {
446+
delete reinterpret_cast<ValueT*>(cache.idToObject[oldId]);
447+
}
448+
cache.idToObject.erase(oldId);
443449
std::unique_ptr<ValueT const, Deleter<ValueT const>> result(DataRefUtils::as<CCDBSerialized<ValueT>>(ref).release(), false);
444450
void* obj = (void*)result.get();
445451
callbacks.call<CallbackService::Id::CCDBDeserialised>((ConcreteDataMatcher&)matcher, (void*)obj);
446452
cache.idToObject[id] = obj;
447-
LOGP(info, "Replacing cached entry {} with {} for {} ({})", oldId.value, id.value, path, obj);
448-
oldId.value = id.value;
453+
LOGP(info, "Replacing cached entry {} ({}) with {} ({}) for {} ({})", oldId.value, oldId.etag.data(), id.value, id.etag.data(), path, obj);
454+
oldId = id;
449455
return result;
450456
} else {
451457
throw runtime_error("Attempt to extract object from message with unsupported serialization type");
@@ -495,6 +501,8 @@ class InputRecord
495501
// keep around an instance of the associated object and deserialise it only when
496502
// it's updated.
497503
auto id = ObjectCache::Id::fromRef(ref);
504+
auto metadata = DataRefUtils::extractCCDBHeaders(ref);
505+
id.etag = metadata.count("ETag") ? metadata.at("ETag") : "";
498506
ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification};
499507
// If the matcher does not have an entry in the cache, deserialise it
500508
// and cache the deserialised object at the given id.
@@ -504,21 +512,23 @@ class InputRecord
504512
auto cacheEntry = cache.matcherToMetadataId.find(path);
505513
if (cacheEntry == cache.matcherToMetadataId.end()) {
506514
cache.matcherToMetadataId.insert(std::make_pair(path, id));
507-
cache.idToMetadata[id] = DataRefUtils::extractCCDBHeaders(ref);
508-
LOGP(info, "Caching CCDB metadata {}: {}", id.value, path);
515+
cache.idToMetadata[id] = metadata;
516+
LOGP(info, "Caching CCDB metadata {} ({}): {}", id.value, id.etag.data(), path);
509517
return cache.idToMetadata[id];
510518
}
511519
auto& oldId = cacheEntry->second;
512520
// The id in the cache is the same, let's simply return it.
513-
if (oldId.value == id.value) {
514-
LOGP(debug, "Returning cached CCDB metatada {}: {}", id.value, path);
515-
return cache.idToMetadata[id];
521+
// If the etag is present in both, we compare etags, otherwise we compare values
522+
if (oldId == id) {
523+
LOGP(debug, "Returning cached CCDB metatada {} ({}): {}", oldId.value, oldId.etag.data(), path);
524+
return cache.idToMetadata[oldId];
516525
}
517526
// The id in the cache is different. Let's destroy the old cached entry
518527
// and create a new one.
519-
LOGP(info, "Replacing cached entry {} with {} for {}", oldId.value, id.value, path);
520-
cache.idToMetadata[id] = DataRefUtils::extractCCDBHeaders(ref);
521-
oldId.value = id.value;
528+
LOGP(info, "Replacing cached entry {} ({}) with {} ({}) for {}", oldId.value, oldId.etag.data(), id.value, id.etag.data(), path);
529+
cache.idToMetadata.erase(oldId);
530+
cache.idToMetadata[id] = metadata;
531+
oldId = id;
522532
return cache.idToMetadata[id];
523533
}
524534

Framework/Core/include/Framework/ObjectCache.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ namespace o2::framework
2323
struct ObjectCache {
2424
struct Id {
2525
int64_t value;
26+
std::string etag;
2627
static Id fromRef(DataRef& ref)
2728
{
28-
return {reinterpret_cast<int64_t>(ref.payload)};
29+
return {reinterpret_cast<int64_t>(ref.payload), ""};
2930
}
3031
bool operator==(const Id& other) const
3132
{
33+
if (!etag.empty() && !other.etag.empty()) {
34+
return etag == other.etag;
35+
}
3236
return value == other.value;
3337
}
3438

0 commit comments

Comments
 (0)