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