ATLAS Offline Software
Loading...
Searching...
No Matches
CondCont.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
10
11
17#include "GaudiKernel/MsgStream.h"
18#include <iostream>
19
20
22std::string CondContBase::s_cleanerSvcName = "Athena::ConditionsCleanerSvc";
23
24
39int CondContBase::Compare::overlap (const EventContext& ctx,
40 const RangeKey& oldRange,
41 RangeKey& newRange) const
42{
43 // |--- oldRange ---|
44 // |--- newRange ---|
45 if (newRange.m_stop <= oldRange.m_start) {
46 return 0;
47 }
48
49 // |--- oldRange ---|
50 // |--- newRange ---|
51 if (oldRange.m_stop <= newRange.m_start) {
52 return 0;
53 }
54
55 // |--- oldRange ---|
56 // |--- newRange ---|
57 if (newRange.m_start >= oldRange.m_start &&
58 newRange.m_stop <= oldRange.m_stop)
59 {
60 return -1;
61 }
62
63 // Current IOV key.
64 key_type cur;
65 if (newRange.m_range.start().isTimeStamp()) {
66 cur = keyFromTimestamp (ctx.eventID());
67 }
68 else {
69 EventIDBase eid = ctx.eventID();
70 if (ctx.hasExtension()) {
71 EventIDBase::number_type conditionsRun =
73 if (conditionsRun != EventIDBase::UNDEFNUM) {
74 eid.set_run_number (conditionsRun);
75 }
76 }
77 cur = keyFromRunLBN (eid);
78 }
79
80 // Either this:
81 // |--- oldRange ---|
82 // |--- newRange ---|
83 //
84 // Or this
85 // |--- oldRange ---|
86 // |--- newRange ---|
87 // with the current IOV key after the end of oldRange.
88 //
89 // In either case, we start the start of newRange to the end of oldRange.
90 if (newRange.m_stop > oldRange.m_stop &&
91 (newRange.m_start >= oldRange.m_start ||
92 cur > oldRange.m_stop))
93 {
94 newRange.m_start = oldRange.m_stop;
95 if (oldRange.m_range.stop().isTimeStamp()) {
96 // If this is a mixed key, we need to copy only the timestamp part.
97 EventIDBase oldId = oldRange.m_range.stop();
98 EventIDBase newId = newRange.m_range.start();
99 newRange.m_range = EventIDRange (EventIDBase (newId.run_number(),
100 newId.event_number(),
101 oldId.time_stamp(),
102 oldId.time_stamp_ns_offset(),
103 newId.lumi_block(),
104 newId.bunch_crossing_id()),
105 newRange.m_range.stop());
106 }
107 else {
108 newRange.m_range = EventIDRange (oldRange.m_range.stop(),
109 newRange.m_range.stop());
110 }
111 }
112
113
114 // |--- oldRange ---|
115 // |--- newRange ---|
116 else if (newRange.m_start < oldRange.m_start &&
117 newRange.m_stop > oldRange.m_start)
118 {
119 // Change the end of newRange to the start of oldRange.
120 newRange.m_stop = oldRange.m_start;
121 if (oldRange.m_range.start().isTimeStamp()) {
122 // If this is a mixed key, we need to copy only the timestamp part.
123 EventIDBase oldId = oldRange.m_range.start();
124 EventIDBase newId = newRange.m_range.stop();
125 newRange.m_range = EventIDRange (newRange.m_range.start(),
126 EventIDBase (newId.run_number(),
127 newId.event_number(),
128 oldId.time_stamp(),
129 oldId.time_stamp_ns_offset(),
130 newId.lumi_block(),
131 newId.bunch_crossing_id()));
132 }
133 else {
134 newRange.m_range = EventIDRange (newRange.m_range.start(),
135 oldRange.m_range.start());
136 }
137 }
138
139 // Should have handled all cases by now!
140 else {
141 std::abort();
142 }
143
144 return 1;
145}
146
147
159 const RangeKey& newRange) const
160{
161 // |--- range ---|
162 // |--- newRange ....
163 if (newRange.m_start < range.m_start) {
164 return 0;
165 }
166
167 // |--- range ---|
168 // |--- newRange ....
169 if (newRange.m_start > range.m_stop) {
170 return 0;
171 }
172
173 // |--- range ----------------|
174 // |--- newRange ---|
175 if (newRange.m_stop <= range.m_stop) {
176 return -1;
177 }
178
179 // |--- range ----|
180 // |--- newRange ---|
181 range.m_stop = newRange.m_stop;
182 range.m_range = EventIDRange (range.m_range.start(),
183 newRange.m_range.stop());
184 return 1;
185}
186
187
192{
193 return "CondCont";
194}
195
196
201{
202 if (code == static_cast<code_t> (CondContStatusCode::DUPLICATE)) {
203 return "DUPLICATE";
204 }
205 else if (code == static_cast<code_t> (CondContStatusCode::OVERLAP)) {
206 return "OVERLAP";
207 }
208 else if (code == static_cast<code_t> (CondContStatusCode::EXTENDED)) {
209 return "EXTENDED";
210 }
211 return StatusCode::Category::message (code);
212}
213
214
219{
220 return code == static_cast<code_t>( CondContStatusCode::DUPLICATE ) ||
221 code == static_cast<code_t>( CondContStatusCode::OVERLAP ) ||
222 code == static_cast<code_t>( CondContStatusCode::EXTENDED ) ||
223 code == static_cast<code_t>( CondContStatusCode::SUCCESS );
224}
225
226
229{
230 return code == static_cast<code_t> (CondContStatusCode::DUPLICATE);
231}
232
233
236{
237 return isDuplicate (code.getCode());
238}
239
240
243{
244 return code == static_cast<code_t> (CondContStatusCode::OVERLAP);
246
247
250{
251 return isOverlap (code.getCode());
252}
253
254
257{
258 return code == static_cast<code_t> (CondContStatusCode::EXTENDED);
260
261
264{
265 return isExtended (code.getCode());
266}
267
268
269STATUSCODE_ENUM_IMPL (CondContStatusCode, CondContBase::Category)
270
271
272
280
281
286{
287 list (std::cout);
288}
289
290
295{
296 return m_condSet.size();
297}
298
299
320size_t CondContBase::trim (const std::vector<key_type>& runLbnKeys, const std::vector<key_type>& TSKeys)
321{
322 if (m_keyType == KeyType::RUNLBN) {
323 return m_condSet.trim (runLbnKeys);
324 }
325
327 return m_condSet.trim ( TSKeys );
328 }
329
330
331 if (m_keyType == KeyType::MIXED) {
332 //For mixed containers, first trim inner container based in TimeStamps
333 size_t nTrimmed=0;
334 for (const typename CondContSet::value_type& ent : m_condSet.range()) {
335 const CondContSet* tsmap = reinterpret_cast<const CondContSet*> (ent.second);
336 //size_t before=tsmap->size();
337 CondContSet* tsmap_nc ATLAS_THREAD_SAFE = const_cast<CondContSet*>(tsmap);
338 // Trim inner containers, allowing the removal of all elements.
339 // See ATLASRECTS-7421.
340 size_t ntrim=tsmap_nc->trim (TSKeys, true);
341 nTrimmed+=ntrim;
342 //std::cout << "WL: Trimming inner container for clid " << m_clid << " (" << ntrim << " out of " << before << ", nKeys= " << TSKeys.size() << ")" << std::endl;
343 }
344 // Then trim outer container based on run-LB.
345 size_t outerTrimmed=m_condSet.trim(runLbnKeys);
346 //std::cout << "WL: Removing outer sets " << outerTrimmed << ", remaining " << m_condSet.size() << std::endl;
347 //FIXME: The number returned may be inaccurate, only correct if the outer container
348 //has exactly one element left by the time it gets removed.
349 return nTrimmed+outerTrimmed;
350 }
351
352//Arrive here for KeyType::SINGLE .. do nothing.
353 return 0;
355
356
362{
363 m_condSet.clear();
364}
365
366
371 * This would normally be done through RCU service.
372 * Defined here for purposes of testing.
373 */
374void
375CondContBase::quiescent (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
376{
377 m_condSet.quiescent (ctx);
378}
379
380
383 */
385{
386 return m_condSet.nInserts();
387}
388
389
394{
395 return m_condSet.maxSize();
396}
397
398
411 CLID clid,
412 const DataObjID& id,
414 std::shared_ptr<CondContSet::IPayloadDeleter> payloadDeleter,
415 size_t capacity)
416 : m_keyType (keyType),
417 m_clid (clid),
418 m_id (id),
419 m_proxy (proxy),
420 m_condSet (Updater_t (rcusvc), std::move(payloadDeleter), capacity),
421 m_cleanerSvc (s_cleanerSvcName, "CondContBase"),
422 m_deps (DepSet::Updater_t(), 16)
423{
424 if (!m_cleanerSvc.retrieve().isSuccess()) {
425 std::abort();
426 }
427}
428
429
445StatusCode
446CondContBase::insertBase (const EventIDRange& r,
448 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
449{
450 EventIDBase start = r.start();
451 EventIDBase stop = r.stop();
452
453 key_type start_key, stop_key;
454
455 if (m_keyType == KeyType::MIXED) {
456 if (start.run_number() == EventIDBase::UNDEFNUM ||
457 stop.run_number() == EventIDBase::UNDEFNUM)
458 {
459 MsgStream msg (Athena::getMessageSvc(), title());
460 msg << MSG::ERROR << "CondContBase::insertBase: "
461 << "Run part of range invalid in mixed container."
462 << endmsg;
463 return StatusCode::FAILURE;
464 }
465
466 start_key = keyFromRunLBN (start);
467 stop_key = keyFromRunLBN (stop);
468 }
469 else if (start.isTimeStamp() && stop.isTimeStamp()) {
470 if (m_keyType == KeyType::SINGLE) {
472 }
473 else if (m_keyType != KeyType::TIMESTAMP) {
474 MsgStream msg (Athena::getMessageSvc(), title());
475 msg << MSG::ERROR << "CondContBase::insertBase: "
476 << "Timestamp key used in non-timestamp container."
477 << endmsg;
478 return StatusCode::FAILURE;
479 }
480
481 start_key = keyFromTimestamp (start);
482 stop_key = keyFromTimestamp (stop);
483 }
484
485 else if (start.run_number() != EventIDBase::UNDEFNUM &&
486 stop.run_number() != EventIDBase::UNDEFNUM)
487 {
488 if (m_keyType == KeyType::SINGLE) {
490 }
491 else if (m_keyType != KeyType::RUNLBN) {
492 MsgStream msg (Athena::getMessageSvc(), title());
493 msg << MSG::ERROR << "CondContBase::insertBase: "
494 << "Run/LBN key used in non-Run/LBN container."
495 << endmsg;
496 return StatusCode::FAILURE;
498
499 start_key = keyFromRunLBN (start);
500 stop_key = keyFromRunLBN (stop);
501 }
502
503 else {
504 MsgStream msg (Athena::getMessageSvc(), title());
505 msg << MSG::ERROR << "CondContBase::insertBase: EventIDRange " << r
506 << " is neither fully RunEvent nor TimeStamp"
507 << endmsg;
508 return StatusCode::FAILURE;
509 }
510
512 m_condSet.emplace( RangeKey(r, start_key, stop_key),
513 std::move(t),
515 ctx );
516
517 if (reslt == CondContSet::EmplaceResult::DUPLICATE)
518 {
520 }
521 else if (reslt == CondContSet::EmplaceResult::EXTENDED)
522 {
524 }
525 else if (reslt == CondContSet::EmplaceResult::OVERLAP) {
527 }
528
529 return this->inserted (ctx);
530}
531
532
538StatusCode
539CondContBase::eraseBase (const EventIDBase& t,
540 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
541{
542 switch (m_keyType) {
543 case KeyType::RUNLBN:
544 if (!t.isRunLumi()) {
545 MsgStream msg (Athena::getMessageSvc(), title());
546 msg << MSG::ERROR << "CondContBase::erase: "
547 << "Non-Run/LBN key used in Run/LBN container."
548 << endmsg;
549 return StatusCode::FAILURE;
550 }
551 m_condSet.erase (CondContBase::keyFromRunLBN (t), ctx);
552 break;
554 if (!t.isTimeStamp()) {
555 MsgStream msg (Athena::getMessageSvc(), title());
556 msg << MSG::ERROR << "CondContBase::erase: "
557 << "Non-Timestamp key used in timestamp container."
558 << endmsg;
559 return StatusCode::FAILURE;
560 }
562 break;
563 case KeyType::SINGLE:
564 break;
565 default:
566 std::abort();
567 }
568 return StatusCode::SUCCESS;
569}
570
571
581 */
582StatusCode
583CondContBase::extendLastRangeBase (const EventIDRange& newRange,
584 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
585{
586 key_type start;
587 key_type stop;
588 switch (m_keyType) {
589 case KeyType::RUNLBN:
590 case KeyType::MIXED: // To handle the extension case of insertMixed().
591 if (!newRange.start().isRunLumi()) {
592 MsgStream msg (Athena::getMessageSvc(), title());
593 msg << MSG::ERROR << "CondContBase::extendLastRange: "
594 << "Non-Run/LBN range used in Run/LBN container."
595 << endmsg;
596 return StatusCode::FAILURE;
597 }
598 start = keyFromRunLBN (newRange.start());
599 stop = keyFromRunLBN (newRange.stop());
600 break;
602 if (!newRange.start().isTimeStamp()) {
603 MsgStream msg (Athena::getMessageSvc(), title());
604 msg << MSG::ERROR << "CondContBase::extendLastRange: "
605 << "Non-timestamp range used in timestamp container."
606 << endmsg;
607 return StatusCode::FAILURE;
608 }
609 start = keyFromTimestamp (newRange.start());
610 stop = keyFromTimestamp (newRange.stop());
611 break;
612 case KeyType::SINGLE:
613 // Empty container.
614 return StatusCode::FAILURE;
615 default:
616 std::abort();
617 }
618
619 if (m_condSet.extendLastRange (RangeKey (newRange, start, stop), ctx) >= 0)
620 {
621 return StatusCode::SUCCESS;
622 }
623 return StatusCode::FAILURE;
624}
625
626
637const void* CondContBase::findBase (const EventIDBase& t,
638 EventIDRange const** r) const
640 const void* ptr = nullptr;
641 key_type key;
642 switch (m_keyType) {
643 case KeyType::RUNLBN:
644 case KeyType::MIXED:
645 if (ATH_UNLIKELY (!t.isRunLumi())) {
647 msg << MSG::ERROR << "CondContBase::findBase: "
648 << "Non-Run/LBN key used in Run/LBN container."
649 << endmsg;
650 return nullptr;
651 }
652 key = keyFromRunLBN (t);
653 break;
655 if (ATH_UNLIKELY (!t.isTimeStamp())) {
656 MsgStream msg (Athena::getMessageSvc(), title());
657 msg << MSG::ERROR << "CondContBase::findBase: "
658 << "Non-timestamp key used in timestamp container."
659 << endmsg;
660 return nullptr;
661 }
662 key = keyFromTimestamp (t);
663 break;
664 case KeyType::SINGLE:
665 // Empty container.
666 return nullptr;
667 default:
668 std::abort();
669 }
670
672 if (it && key < it->first.m_stop) {
673 if (r) {
674 *r = &it->first.m_range;
675 }
676 ptr = it->second;
677 }
678
679 return ptr;
680}
681
682
686StatusCode CondContBase::inserted (const EventContext& ctx)
687{
688 return m_cleanerSvc->condObjAdded (ctx, *this);
689}
690
691
697{
698 m_deps.insert (dep);
699}
700
701
705std::vector<CondContBase*> CondContBase::getDeps()
706{
707 return std::vector<CondContBase*> (m_deps.begin(), m_deps.end());
708}
710
711
716 */
717void CondContBase::setCleanerSvcName (const std::string& name)
718{
719 s_cleanerSvcName = name;
720}
721
722
727void CondContBase::insertError (CLID usedCLID) const
728{
729 MsgStream msg (Athena::getMessageSvc(), title());
730 msg << MSG::ERROR << "CondCont<T>::insert: Not most-derived class; "
731 << "CLID used: " << usedCLID
732 << "; container CLID: " << m_clid
733 << endmsg;
734}
735
736
741{
742 return m_condSet.deleter().delfcn();
743}
744
745
749std::string CondContBase::title() const
750{
751 return m_id.fullKey();
752}
753
754
755//****************************************************************************
756
757
761 */
762void CondContSingleBase::list (std::ostream& ost) const
763{
764 ost << "id: " << id() << " proxy: " << proxy() << " ["
765 << entries() << "] entries" << std::endl;
766 forEach ([&] (const CondContSet::value_type& ent)
767 { ost << ent.first.m_range << " " << ent.second << std::endl; });
768}
769
774std::vector<EventIDRange>
776{
777 std::vector<EventIDRange> r;
778 r.reserve (entries());
779
780 forEach ([&] (const CondContSet::value_type& ent)
781 { r.push_back (ent.first.m_range); });
782
783 return r;
784}
786
807StatusCode
809 void* obj,
810 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
811{
812 return insertBase (r,
814 ctx);
815}
816
817
825bool
826CondContSingleBase::range (const EventIDBase& t, EventIDRange& r) const
827{
828 const EventIDRange* rp = nullptr;
829 if (findBase (t, &rp) != nullptr) {
830 r = *rp;
831 return true;
832 }
833 return false;
834}
835
836
842StatusCode
843CondContSingleBase::erase (const EventIDBase& t,
844 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
845{
846 return CondContBase::eraseBase (t, ctx);
847}
848
849
860StatusCode
861CondContSingleBase::extendLastRange (const EventIDRange& newRange,
862 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
863{
864 return CondContBase::extendLastRangeBase (newRange, ctx);
865}
866
867
878 CLID clid,
879 const DataObjID& id,
881 std::shared_ptr<CondContSet::IPayloadDeleter> payloadDeleter,
882 size_t capacity)
883 : CondContBase (rcusvc, KeyType::SINGLE, clid, id, proxy,
884 std::move(payloadDeleter), capacity)
885{
886}
887
888
889//****************************************************************************
890
891
902 CLID clid,
903 const DataObjID& id,
905 std::shared_ptr<CondContSet::IPayloadDeleter> payloadDeleter,
906 size_t capacity)
907 : CondContBase (rcusvc, KeyType::MIXED, clid, id, proxy,
908 std::make_shared<Athena::CondObjDeleter<CondContSet> > (rcusvc),
909 capacity),
910 m_rcusvc (rcusvc),
911 m_payloadDeleter (std::move(payloadDeleter))
912{
913}
914
915
920void CondContMixedBase::list (std::ostream& ost) const
921{
922 ost << "id: " << id() << " proxy: " << proxy() << " ["
923 << CondContBase::entries() << "] run+lbn entries" << std::endl;
924 forEach ([&] (const CondContSet::value_type& ent)
925 {
926 const CondContSet* tsmap =
927 reinterpret_cast<const CondContSet*> (ent.second);
928 if (tsmap->empty()) {
929 ost << ent.first.m_range << " (empty tsmap)" << std::endl;
930 }
931 else {
932 for (const CondContSet::value_type& ent2 : tsmap->range()) {
933 ost << ent2.first.m_range << " " << ent2.second << std::endl;
934 }
935 }
936 });
937}
938
939
944{
945 size_t nent = 0;
946 forEach ([&] (const CondContSet::value_type& ent) {
947 const CondContSet* tsmap =
948 reinterpret_cast<const CondContSet*> (ent.second);
949 nent += tsmap->size();
950 });
951 return nent;
952}
953
954
958std::vector<EventIDRange>
960{
961 std::vector<EventIDRange> r;
962 r.reserve (entries()*2);
963
964 forEach ([&] (const CondContSet::value_type& ent)
965 {
966 const CondContSet* tsmap =
967 reinterpret_cast<const CondContSet*> (ent.second);
968 for (const CondContSet::value_type& ent2 : tsmap->range()) {
969 r.push_back (ent2.first.m_range);
970 }
971 });
972
973 return r;
974}
975
976
995StatusCode
997 void* obj,
998 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
999{
1000 return insertMixed (r,
1001 CondContSet::payload_unique_ptr (obj, payloadDelfcn()),
1002 ctx);
1003}
1004
1005
1013bool
1014CondContMixedBase::range (const EventIDBase& t, EventIDRange& r) const
1015{
1016 const EventIDRange* rp = nullptr;
1017 if (findMixed (t, &rp) != nullptr) {
1018 r = *rp;
1019 return true;
1020 }
1021 return false;
1022}
1023
1024
1032StatusCode
1033CondContMixedBase::erase (const EventIDBase& /*t*/,
1034 const EventContext& /*ctx = Gaudi::Hive::currentContext()*/)
1035{
1036 MsgStream msg (Athena::getMessageSvc(), title());
1037 msg << MSG::ERROR << "CondContMixedBase::erase: "
1038 << "erase() is not implemented for mixed containers."
1039 << endmsg;
1040 return StatusCode::FAILURE;
1041}
1042
1043
1056StatusCode
1057CondContMixedBase::extendLastRange (const EventIDRange& /*newRange*/,
1058 const EventContext& /*ctx = Gaudi::Hive::currentContext()*/)
1059{
1060 MsgStream msg (Athena::getMessageSvc(), title());
1061 msg << MSG::ERROR << "CondContMixedBase::extendLastRange: "
1062 << "extendLastRange() is not implemented for mixed containers."
1063 << endmsg;
1064 return StatusCode::FAILURE;
1065}
1066
1067
1083StatusCode
1086 const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
1087{
1088 // Serialize insertions.
1089 std::lock_guard<std::mutex> lock (m_mutex);
1090
1091 const EventIDRange* range = nullptr;
1092 const void* tsmap_void = findBase (r.start(), &range);
1094 const_cast<CondContSet*>(reinterpret_cast<const CondContSet*> (tsmap_void));
1095
1096 // Only test start timestamp. stop timestamp may be missing
1097 // for open-ended ranges.
1098 key_type start_key=0; //If there is no TimeStamp in start, assume infinite range
1099 if (r.start().isTimeStamp() ) {
1100 start_key = keyFromTimestamp (r.start());
1101 }
1102
1103 key_type stop_key = keyFromTimestamp (r.stop());
1104
1105 StatusCode sc = StatusCode::SUCCESS;
1106 sc.ignore();
1107 if (tsmap) {
1108 if (r.start().run_number() != range->start().run_number() ||
1109 r.stop().run_number() != range->stop().run_number() ||
1110 r.start().lumi_block() != range->start().lumi_block() ||
1111 r.stop().lumi_block() != range->stop().lumi_block())
1112 {
1113 // Run+lbn part doesn't match. If this range contains only a single
1114 // timestamp range which matches the timestamp part of the key,
1115 // then try to extend it. Otherwise, give an error.
1116
1117 bool extended = false;
1118 if (tsmap->size() == 1) {
1119 CondContSet::const_iterator elt = tsmap->find (start_key);
1120 if (elt) {
1121 if (elt->first.m_start == start_key &&
1122 elt->first.m_stop == stop_key)
1123 {
1124 if (extendLastRangeBase (r, ctx).isSuccess())
1125 {
1127 sc.ignore();
1128 extended = true;
1129
1130 // We also need to update the ending run+lbn value
1131 // for each entry in the tsmap.
1132 // (This doesn't affect sorting within the tsmap.)
1133 // There's a potential race here: a lookup happening
1134 // between the extendLastRangeBase above and the updateRanges
1135 // below can get a range with an unupdated run/lbn.
1136 // It would be cleaner to do the extend/update as a single
1137 // operation, but for now we work around by having findMixed
1138 // retry if the run/lbn being sought is in the range
1139 // of the entry that's actually found.
1140 tsmap->updateRanges ([&] (RangeKey& k)
1141 { EventIDBase start = k.m_range.start();
1142 EventIDBase stop = k.m_range.stop();
1143 stop.set_run_number(r.stop().run_number());
1144 stop.set_lumi_block(r.stop().lumi_block());
1145 k.m_range = EventIDRange (start, stop);
1146 },
1147 ctx);
1148 }
1149 }
1150 }
1151 }
1152
1153 if (!extended) {
1154 MsgStream msg (Athena::getMessageSvc(), title());
1155 msg << MSG::ERROR << "CondContMixedBase::insertMixed: "
1156 << "Run+lbn part of new range doesn't match existing range, "
1157 << "or can't extend. "
1158 << "New: " << r << "; existing: " << *range
1159 << endmsg;
1160 return StatusCode::FAILURE;
1161 }
1162 }
1163 }
1164 else {
1165 auto newmap = std::make_unique<CondContSet>
1167 tsmap = newmap.get();
1168 sc = insertBase (r, std::move (newmap), ctx);
1169 if (sc.isFailure()) {
1170 return sc;
1171 }
1172 else if (Category::isDuplicate (sc)) {
1173 // Shouldn't happen...
1174 std::abort();
1175 }
1176 }
1177
1178 CondContSet::EmplaceResult reslt =
1179 tsmap->emplace ( RangeKey(r, start_key, stop_key),
1180 std::move(t), false, ctx );
1181
1182 if (reslt == CondContSet::EmplaceResult::OVERLAP) {
1184 }
1185 else if (Category::isExtended (sc)) {
1186 return sc;
1187 }
1188 else if (reslt == CondContSet::EmplaceResult::DUPLICATE)
1189 {
1191 }
1192 else if (reslt == CondContSet::EmplaceResult::EXTENDED)
1193 {
1194 std::abort(); // Shouldn't happen.
1195 }
1196 return this->inserted (ctx);
1197 //return sc;
1198}
1199
1200
1210const void*
1211CondContMixedBase::findMixed (const EventIDBase& t,
1212 EventIDRange const** r) const
1213{
1214 if (!t.isTimeStamp()) {
1215 MsgStream msg (Athena::getMessageSvc(), title());
1216 msg << MSG::ERROR << "CondContMixedBase::findMixed: "
1217 << "No valid timestamp in key used with mixed container."
1218 << endmsg;
1219 return nullptr;
1220 }
1221
1222 auto dostall = []() { CxxUtils::stall(); return true; };
1223 const void* ptr = nullptr;
1224 CondContSet::const_iterator it;
1225 do {
1226 ptr = CondContBase::findBase (t, nullptr);
1227 if (!ptr) return nullptr;
1228
1229 const CondContSet* tsmap = reinterpret_cast<const CondContSet*> (ptr);
1230 key_type key = keyFromTimestamp (t);
1231 it = tsmap->find (key);
1232
1233 if (it && key < it->first.m_stop) {
1234 if (r) {
1235 *r = &it->first.m_range;
1236 }
1237 ptr = it->second;
1238 }
1239 else {
1240 ptr = nullptr;
1241 }
1242
1243 // When we extend a range in a mixed container, the run/lbn fields
1244 // in the ts map are extended as a separate step. This means
1245 // that there is a window in which we can successfully look up
1246 // an entry, but the range we get will have the old, unextended
1247 // run/lbn. Work around here: if the run/lbn we're looking
1248 // for isn't in the range we get, then try again.
1249 } while (ptr &&
1250 keyFromRunLBN (t) >= keyFromRunLBN (it->first.m_range.stop()) &&
1251 dostall());
1252
1253 return ptr;
1254}
1255
1256
#define endmsg
#define ATH_UNLIKELY(x)
Hold mappings of ranges to condition objects.
CondContStatusCode
Define extended status codes used by CondCont.
Definition CondCont.h:108
uint32_t CLID
The Class ID type.
ReadCards * rp
static Double_t sc
Define macros for attributes used to control the static checker.
Interface for RCU service.
Definition IRCUSvc.h:40
EventIDBase::number_type conditionsRun() const
Status code category for ContCont.
Definition CondCont.h:148
StatusCode::code_t code_t
Definition CondCont.h:150
static bool isOverlap(code_t code)
Helper to test whether a code is OVERLAP.
Definition CondCont.cxx:242
virtual const char * name() const override
Name of the category.
Definition CondCont.cxx:191
virtual bool isSuccess(code_t code) const override
Is code considered success?
Definition CondCont.cxx:218
virtual std::string message(code_t code) const override
Description for code within this category.
Definition CondCont.cxx:200
static bool isExtended(code_t code)
Helper to test whether a code is EXTENDED.
Definition CondCont.cxx:256
static bool isDuplicate(code_t code)
Helper to test whether a code is DUPLICATE.
Definition CondCont.cxx:228
StatusCode insertBase(const EventIDRange &r, CondContSet::payload_unique_ptr t, const EventContext &ctx=Gaudi::Hive::currentContext())
Insert a new conditions object.
Definition CondCont.cxx:446
CLID m_clid
CLID of the most-derived CondCont.
Definition CondCont.h:666
StatusCode extendLastRangeBase(const EventIDRange &newRange, const EventContext &ctx=Gaudi::Hive::currentContext())
Extend the range of the last IOV.
Definition CondCont.cxx:583
void insertError(CLID usedCLID) const
Helper to report an error due to using a base class for insertion.
Definition CondCont.cxx:727
void forEach(const FUNC &func) const
Call func on each entry in the container.
CondContSet::Updater_t Updater_t
Definition CondCont.h:519
size_t nInserts() const
Return the number times an item was inserted into the map.
Definition CondCont.cxx:384
void setProxy(SG::DataProxy *)
Set the associated DataProxy.
Definition CondCont.cxx:276
size_t maxSize() const
Return the maximum size of the map.
Definition CondCont.cxx:393
KeyType
Type of key used for this container.
Definition CondCont.h:180
@ SINGLE
Either TIMESTAMP or RUNLBN, but nothing's been put in the container yet, so we don't know which one.
Definition CondCont.h:183
@ MIXED
Mixed Run+lbn / timestamp container.
Definition CondCont.h:192
@ TIMESTAMP
Container uses timestamp keys.
Definition CondCont.h:186
@ RUNLBN
Container uses run+lbn keys.
Definition CondCont.h:189
std::string title() const
Description of this container to use for MsgStream.
Definition CondCont.cxx:749
void clear()
Remove all entries in the container.
Definition CondCont.cxx:361
std::atomic< KeyType > m_keyType
Key type of this container.
Definition CondCont.h:663
const void * findBase(const EventIDBase &t, EventIDRange const **r) const
Internal lookup function.
Definition CondCont.cxx:637
CondContSet m_condSet
Set of mapped objects.
Definition CondCont.h:675
static std::string s_cleanerSvcName ATLAS_THREAD_SAFE
Name of the global conditions cleaner service.
Definition CondCont.h:686
StatusCode eraseBase(const EventIDBase &t, const EventContext &ctx=Gaudi::Hive::currentContext())
Erase the first element not less than t.
Definition CondCont.cxx:539
delete_function * delfcn() const
Return the deletion function for this container.
Definition CondCont.cxx:740
void quiescent(const EventContext &ctx=Gaudi::Hive::currentContext())
Mark that this thread is no longer accessing data from this container.
Definition CondCont.cxx:375
ServiceHandle< Athena::IConditionsCleanerSvc > m_cleanerSvc
Handle to the cleaner service.
Definition CondCont.h:678
void addDep(CondContBase *dep)
Declare another conditions container that depends on this one.
Definition CondCont.cxx:696
static key_type keyFromTimestamp(const EventIDBase &b)
Make a timestamp key from an EventIDBase.
DepSet m_deps
Definition CondCont.h:683
static key_type keyFromRunLBN(const EventIDBase &b)
Make a run+lbn key from an EventIDBase.
virtual size_t entries() const
Return the number of conditions objects in the container.
Definition CondCont.cxx:294
DataObjID m_id
CLID+key for this container.
Definition CondCont.h:669
CxxUtils::ConcurrentRangeMap< RangeKey, key_type, void, Compare, Athena::RCUUpdater > CondContSet
Definition CondCont.h:517
StatusCode inserted(const EventContext &ctx)
Tell the cleaner that a new object was added to the container.
Definition CondCont.cxx:686
KeyType keyType() const
Return the key type for this container.
CondContBase(Athena::IRCUSvc &rcusvc, KeyType keytype, CLID clid, const DataObjID &id, SG::DataProxy *proxy, std::shared_ptr< CondContSet::IPayloadDeleter > payloadDeleter, size_t capacity)
Internal constructor.
Definition CondCont.cxx:409
CLID clid() const
Return the CLID of the most-derived CondCont.
uint64_t key_type
Type used to store an IOV time internally.
Definition CondCont.h:204
SG::DataProxy * m_proxy
Associated DataProxy.
Definition CondCont.h:672
virtual bool range(const EventIDBase &t, EventIDRange &r) const =0
Return the mapped validity range for an IOV time.
SG::DataProxy * proxy()
Return the associated DataProxy, if any.
virtual size_t trim(const std::vector< key_type > &runLbnKeys, const std::vector< key_type > &TSKeys)
Remove unused entries from the front of the list.
Definition CondCont.cxx:320
void print() const
Dump the container to cout.
Definition CondCont.cxx:285
const DataObjID & id() const
Return CLID/key corresponding to this container.
CondContSet::delete_function delete_function
Definition CondCont.h:520
std::vector< CondContBase * > getDeps()
Return the list of conditions containers that depend on this one.
Definition CondCont.cxx:705
virtual void list(std::ostream &ost) const =0
Dump the container contents for debugging.
CxxUtils::ConcurrentPtrSet< CondContBase, CxxUtils::SimpleUpdater > DepSet
Other conditions dependencies that depend on this one, as inferred by addDependency calls.
Definition CondCont.h:682
delete_function * payloadDelfcn() const
Return the payload deletion function for this container.
virtual void list(std::ostream &ost) const override final
Dump the container contents for debugging.
Definition CondCont.cxx:920
const void * findMixed(const EventIDBase &t, EventIDRange const **r) const
Internal lookup function.
virtual std::vector< EventIDRange > ranges() const override final
Return all IOV validity ranges defined in this container.
Definition CondCont.cxx:959
StatusCode insertMixed(const EventIDRange &r, CondContBase::CondContSet::payload_unique_ptr t, const EventContext &ctx=Gaudi::Hive::currentContext())
Insert a new conditions object.
virtual size_t entries() const override final
Return the number of conditions objects in the container.
Definition CondCont.cxx:943
virtual StatusCode erase(const EventIDBase &t, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Erase the first element not less than t.
Athena::IRCUSvc & m_rcusvc
Need to remember the RCU svc here in order to pass it to the TS maps.
Definition CondCont.h:1185
std::shared_ptr< CondContSet::IPayloadDeleter > m_payloadDeleter
Deletion object for actual payload objects.
Definition CondCont.h:1188
virtual StatusCode typelessInsert(const EventIDRange &r, void *obj, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Insert a new conditions object.
Definition CondCont.cxx:996
std::mutex m_mutex
Mutex for insertions.
Definition CondCont.h:1191
virtual StatusCode extendLastRange(const EventIDRange &newRange, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Extend the range of the last IOV.
CondContMixedBase(Athena::IRCUSvc &rcusvc, CLID clid, const DataObjID &id, SG::DataProxy *proxy, std::shared_ptr< CondContSet::IPayloadDeleter > payloadDeleter, size_t capacity)
Internal constructor.
Definition CondCont.cxx:901
virtual bool range(const EventIDBase &t, EventIDRange &r) const override final
Return the mapped validity range for an IOV time.
virtual StatusCode erase(const EventIDBase &t, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Erase the first element not less than t.
Definition CondCont.cxx:843
CondContSingleBase(Athena::IRCUSvc &rcusvc, CLID clid, const DataObjID &id, SG::DataProxy *proxy, std::shared_ptr< CondContSet::IPayloadDeleter > payloadDeleter, size_t capacity)
Internal constructor.
Definition CondCont.cxx:877
virtual bool range(const EventIDBase &t, EventIDRange &r) const override final
Return the mapped validity range for an IOV time.
Definition CondCont.cxx:826
virtual void list(std::ostream &ost) const override final
Dump the container contents for debugging.
Definition CondCont.cxx:762
virtual StatusCode extendLastRange(const EventIDRange &newRange, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Extend the range of the last IOV.
Definition CondCont.cxx:861
virtual StatusCode typelessInsert(const EventIDRange &r, void *obj, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Insert a new conditions object.
Definition CondCont.cxx:808
virtual std::vector< EventIDRange > ranges() const override final
Return all IOV validity ranges defined in this container.
Definition CondCont.cxx:775
const_iterator_range range() const
Return a range that can be used to iterate over the container.
bool empty() const
Test if the map is empty.
EmplaceResult emplace(const RANGE &range, payload_unique_ptr ptr, bool tryExtend=false, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
Add a new element to the map.
const_iterator find(const key_query_type &key) const
Search for the first item less than or equal to KEY.
void erase(const key_query_type &key, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
Erase the first item less than or equal to KEY.
size_t size() const
Return the current number of elements in the map.
DataProxy provides the registry services for StoreGate.
singleton-like access to IMessageSvc via open function and helper
int r
Definition globals.cxx:22
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
IMessageSvc * getMessageSvc(bool quiet=false)
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
void stall()
Emit stall instruction for use in a spin loop.
Definition stall.h:37
bool first
Definition DeMoScan.py:534
Forward declaration.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
STL namespace.
int extendRange(RangeKey &range, const RangeKey &newRange) const
Possibly extend an existing range at the end.
Definition CondCont.cxx:158
int overlap(const EventContext &ctx, const RangeKey &oldRange, RangeKey &newRange) const
Test if two ranges overlap, and adjust if needed.
Definition CondCont.cxx:39
Range object to store in ConcurrentRangeMap.
Definition CondCont.h:425
key_type m_start
Packed start time.
Definition CondCont.h:436
key_type m_stop
Packed stop time.
Definition CondCont.h:439
EventIDRange m_range
Original range object.
Definition CondCont.h:442
MsgStream & msg
Definition testRead.cxx:32