ATLAS Offline Software
CondCont.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
12 #include "AthenaKernel/CondCont.h"
17 #include "GaudiKernel/MsgStream.h"
18 #include <iostream>
19 
20 
22 std::string CondContBase::s_cleanerSvcName = "Athena::ConditionsCleanerSvc";
23 
24 
39 int 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 
191 const char* CondContBase::Category::name() const
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  }
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);
245 }
246 
247 
250 {
251  return isOverlap (code.getCode());
252 }
253 
254 
257 {
258  return code == static_cast<code_t> (CondContStatusCode::EXTENDED);
259 }
260 
261 
264 {
265  return isExtended (code.getCode());
266 }
267 
268 
269 STATUSCODE_ENUM_IMPL (CondContStatusCode, CondContBase::Category)
270 
271 
272 
277 {
278  m_proxy = proxy;
279 }
280 
281 
286 {
287  list (std::cout);
288 }
289 
290 
294 size_t CondContBase::entries() const
295 {
296  return m_condSet.size();
297 }
298 
299 
320 size_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 
326  if (m_keyType == KeyType::TIMESTAMP) {
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;
354 }
355 
356 
362 {
363  m_condSet.clear();
364 }
365 
366 
374 void
375 CondContBase::quiescent (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
376 {
377  m_condSet.quiescent (ctx);
378 }
379 
380 
385 {
386  return m_condSet.nInserts();
387 }
388 
389 
393 size_t CondContBase::maxSize() const
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), 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 
446 CondContBase::insertBase (const EventIDRange& r,
447  CondContSet::payload_unique_ptr t,
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;
497  }
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 
511  CondContSet::EmplaceResult reslt =
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 
539 CondContBase::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;
553  case KeyType::TIMESTAMP:
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 
583 CondContBase::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;
601  case KeyType::TIMESTAMP:
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 
637 const void* CondContBase::findBase (const EventIDBase& t,
638  EventIDRange const** r) const
639 {
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())) {
646  MsgStream msg (Athena::getMessageSvc(), title());
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;
654  case KeyType::TIMESTAMP:
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 
671  CondContSet::const_iterator it = m_condSet.find (key);
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 
686 StatusCode 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 
705 std::vector<CondContBase*> CondContBase::getDeps()
706 {
707  return std::vector<CondContBase*> (m_deps.begin(), m_deps.end());
708 }
709 
710 
711 
717 void CondContBase::setCleanerSvcName (const std::string& name)
718 {
719  s_cleanerSvcName = name;
720 }
721 
722 
727 void 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 
749 std::string CondContBase::title() const
750 {
751  return m_id.fullKey();
752 }
753 
754 
755 //****************************************************************************
756 
757 
762 void 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 
770 
774 std::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 }
785 
786 
809  void* obj,
810  const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
811 {
812  return insertBase (r,
813  CondContSet::payload_unique_ptr (obj, delfcn()),
814  ctx);
815 }
816 
817 
825 bool
826 CondContSingleBase::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 
843 CondContSingleBase::erase (const EventIDBase& t,
844  const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
845 {
846  return CondContBase::eraseBase (t, ctx);
847 }
848 
849 
861 CondContSingleBase::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  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 (payloadDeleter)
912 {
913 }
914 
915 
920 void 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 
958 std::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 
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 
1013 bool
1014 CondContMixedBase::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 
1032 StatusCode
1033 CondContMixedBase::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 
1056 StatusCode
1057 CondContMixedBase::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 
1083 StatusCode
1084 CondContMixedBase::insertMixed (const EventIDRange& r,
1085  CondContBase::CondContSet::payload_unique_ptr t,
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 
1210 const void*
1211 CondContMixedBase::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);
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 
1261 {
1262  return m_payloadDeleter->delfcn();
1263 }
CondContBase::RangeKey
Range object to store in ConcurrentRangeMap.
Definition: CondCont.h:425
CondContMixedBase::m_mutex
std::mutex m_mutex
Mutex for insertions.
Definition: CondCont.h:1191
beamspotman.r
def r
Definition: beamspotman.py:676
CondContMixedBase::CondContMixedBase
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
CondContBase::keyFromTimestamp
static key_type keyFromTimestamp(const EventIDBase &b)
Make a timestamp key from an EventIDBase.
CondContMixedBase::ranges
virtual std::vector< EventIDRange > ranges() const override final
Return all IOV validity ranges defined in this container.
Definition: CondCont.cxx:959
CondContBase::insertError
void insertError(CLID usedCLID) const
Helper to report an error due to using a base class for insertion.
Definition: CondCont.cxx:727
python.trigbs_prescaleL1.ost
ost
Definition: trigbs_prescaleL1.py:104
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:392
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
CondCont.h
Hold mappings of ranges to condition objects.
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
CondContBase::Category::name
virtual const char * name() const override
Name of the category.
Definition: CondCont.cxx:191
CondContBase::Category::message
virtual std::string message(code_t code) const override
Description for code within this category.
Definition: CondCont.cxx:200
CondContBase::KeyType::RUNLBN
@ RUNLBN
Container uses run+lbn keys.
beamspotman.cur
def cur
Definition: beamspotman.py:671
CondContBase::keyFromRunLBN
static key_type keyFromRunLBN(const EventIDBase &b)
Make a run+lbn key from an EventIDBase.
Atlas::ExtendedEventContext::conditionsRun
EventIDBase::number_type conditionsRun() const
Definition: ExtendedEventContext.h:38
CondContBase::clear
void clear()
Remove all entries in the container.
Definition: CondCont.cxx:361
ExtendedEventContext.h
CondContMixedBase::payloadDelfcn
delete_function * payloadDelfcn() const
Return the payload deletion function for this container.
Definition: CondCont.cxx:1260
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
CondContMixedBase::m_payloadDeleter
std::shared_ptr< CondContSet::IPayloadDeleter > m_payloadDeleter
Deletion object for actual payload objects.
Definition: CondCont.h:1188
skel.it
it
Definition: skel.GENtoEVGEN.py:396
CondContSingleBase::typelessInsert
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
CondContBase::Updater_t
CondContSet::Updater_t Updater_t
Definition: CondCont.h:519
AtlasMcWeight::number_type
unsigned int number_type
Definition: AtlasMcWeight.h:20
CondContBase::KeyType
KeyType
Type of key used for this container.
Definition: CondCont.h:180
CondContBase::addDep
void addDep(CondContBase *dep)
Declare another conditions container that depends on this one.
Definition: CondCont.cxx:696
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
CondContBase::findBase
const void * findBase(const EventIDBase &t, EventIDRange const **r) const
Internal lookup function.
Definition: CondCont.cxx:637
CondContBase::keyType
KeyType keyType() const
Return the key type for this container.
CondContBase::getDeps
std::vector< CondContBase * > getDeps()
Return the list of conditions containers that depend on this one.
Definition: CondCont.cxx:705
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
CondContBase::RangeKey::m_start
key_type m_start
Packed start time.
Definition: CondCont.h:436
CondContBase::list
virtual void list(std::ostream &ost) const =0
Dump the container contents for debugging.
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
CondContBase::m_id
DataObjID m_id
CLID+key for this container.
Definition: CondCont.h:669
ReweightUtils.message
message
Definition: ReweightUtils.py:15
CondContSingleBase::range
virtual bool range(const EventIDBase &t, EventIDRange &r) const override final
Return the mapped validity range for an IOV time.
Definition: CondCont.cxx:826
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
CondContBase::delete_function
CondContSet::delete_function delete_function
Definition: CondCont.h:520
CondContSingleBase::list
virtual void list(std::ostream &ost) const override final
Dump the container contents for debugging.
Definition: CondCont.cxx:762
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
CondContBase::trim
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
Atlas::getExtendedEventContext
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
Definition: ExtendedEventContext.cxx:32
AthUnlikelyMacros.h
CondContSingleBase::CondContSingleBase
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
CondContBase::inserted
StatusCode inserted(const EventContext &ctx)
Tell the cleaner that a new object was added to the container.
Definition: CondCont.cxx:686
CondContMixedBase::insertMixed
StatusCode insertMixed(const EventIDRange &r, CondContBase::CondContSet::payload_unique_ptr t, const EventContext &ctx=Gaudi::Hive::currentContext())
Insert a new conditions object.
Definition: CondCont.cxx:1084
CondContStatusCode::DUPLICATE
@ DUPLICATE
histSizes.code
code
Definition: histSizes.py:129
CondContStatusCode::OVERLAP
@ OVERLAP
CondContMixedBase::list
virtual void list(std::ostream &ost) const override final
Dump the container contents for debugging.
Definition: CondCont.cxx:920
CxxUtils::stall
void stall()
Emit stall instruction for use in a spin loop.
Definition: stall.h:37
CondContBase::range
virtual bool range(const EventIDBase &t, EventIDRange &r) const =0
Return the mapped validity range for an IOV time.
CondContMixedBase::typelessInsert
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
CondContBase::id
const DataObjID & id() const
Return CLID/key corresponding to this container.
CxxUtils::ConcurrentPtrSet::insert
std::pair< const_iterator, bool > insert(const key_type p)
Add an element to the set.
CondContBase::forEach
void forEach(const FUNC &func) const
Call func on each entry in the container.
CondContMixedBase::erase
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:1033
Athena
Some weak symbol referencing magic...
Definition: AthLegacySequence.h:21
CondContMixedBase::range
virtual bool range(const EventIDBase &t, EventIDRange &r) const override final
Return the mapped validity range for an IOV time.
Definition: CondCont.cxx:1014
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CondContMixedBase::m_rcusvc
Athena::IRCUSvc & m_rcusvc
Need to remember the RCU svc here in order to pass it to the TS maps.
Definition: CondCont.h:1185
CondContBase
Base class for all conditions containers.
Definition: CondCont.h:140
CxxUtils::ConcurrentPtrSet::end
const_iterator end() const
Iterator at the end of the set.
DataProxy
DataProxy provides the registry services for StoreGate.
Definition: DataProxy.h:31
CondContBase::m_clid
CLID m_clid
CLID of the most-derived CondCont.
Definition: CondCont.h:666
CondContMixedBase::extendLastRange
virtual StatusCode extendLastRange(const EventIDRange &newRange, const EventContext &ctx=Gaudi::Hive::currentContext()) override final
Extend the range of the last IOV.
Definition: CondCont.cxx:1057
CondContBase::KeyType::TIMESTAMP
@ TIMESTAMP
Container uses timestamp keys.
Athena::IRCUSvc
Interface for RCU service.
Definition: IRCUSvc.h:40
CondContBase::entries
virtual size_t entries() const
Return the number of conditions objects in the container.
Definition: CondCont.cxx:294
CondContBase::RangeKey::m_stop
key_type m_stop
Packed stop time.
Definition: CondCont.h:439
CondContBase::m_proxy
SG::DataProxy * m_proxy
Associated DataProxy.
Definition: CondCont.h:672
CxxUtils::ConcurrentPtrSet::begin
const_iterator begin() const
Iterator at the start of the set.
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
jet::JetTopology::MIXED
@ MIXED
Definition: UncertaintyEnum.h:214
CondContStatusCode::SUCCESS
@ SUCCESS
CondContBase::CondContSet
CxxUtils::ConcurrentRangeMap< RangeKey, key_type, void, Compare, Athena::RCUUpdater > CondContSet
Definition: CondCont.h:517
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:220
CondContSingleBase::erase
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
CxxUtils::ConcurrentPtrSet< CondContBase, CxxUtils::SimpleUpdater >
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
CondContBase::Compare::extendRange
int extendRange(RangeKey &range, const RangeKey &newRange) const
Possibly extend an existing range at the end.
Definition: CondCont.cxx:158
CondContBase::KeyType::MIXED
@ MIXED
Mixed Run+lbn / timestamp container.
CondContBase::ATLAS_THREAD_SAFE
static std::string s_cleanerSvcName ATLAS_THREAD_SAFE
Name of the global conditions cleaner service.
Definition: CondCont.h:686
CondContBase::Category::isOverlap
static bool isOverlap(code_t code)
Helper to test whether a code is OVERLAP.
Definition: CondCont.cxx:242
CondContBase::extendLastRangeBase
StatusCode extendLastRangeBase(const EventIDRange &newRange, const EventContext &ctx=Gaudi::Hive::currentContext())
Extend the range of the last IOV.
Definition: CondCont.cxx:583
CondContStatusCode
CondContStatusCode
Define extended status codes used by CondCont.
Definition: CondCont.h:108
CondContBase::m_cleanerSvc
ServiceHandle< Athena::IConditionsCleanerSvc > m_cleanerSvc
Handle to the cleaner service.
Definition: CondCont.h:678
CondContBase::title
std::string title() const
Description of this container to use for MsgStream.
Definition: CondCont.cxx:749
CondContBase::Category::code_t
StatusCode::code_t code_t
Definition: CondCont.h:150
CondContBase::CondContBase
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
CondContBase::quiescent
void quiescent(const EventContext &ctx=Gaudi::Hive::currentContext())
Mark that this thread is no longer accessing data from this container.
Definition: CondCont.cxx:375
CondContMixedBase::findMixed
const void * findMixed(const EventIDBase &t, EventIDRange const **r) const
Internal lookup function.
Definition: CondCont.cxx:1211
DeMoScan.first
bool first
Definition: DeMoScan.py:536
CondContBase::clid
CLID clid() const
Return the CLID of the most-derived CondCont.
CondContBase::eraseBase
StatusCode eraseBase(const EventIDBase &t, const EventContext &ctx=Gaudi::Hive::currentContext())
Erase the first element not less than t.
Definition: CondCont.cxx:539
CondContBase::key_type
uint64_t key_type
Type used to store an IOV time internally.
Definition: CondCont.h:204
CondContBase::Category::isExtended
static bool isExtended(code_t code)
Helper to test whether a code is EXTENDED.
Definition: CondCont.cxx:256
CondContBase::setProxy
void setProxy(SG::DataProxy *)
Set the associated DataProxy.
Definition: CondCont.cxx:276
CondContBase::m_condSet
CondContSet m_condSet
Set of mapped objects.
Definition: CondCont.h:675
CondContBase::Compare::overlap
int overlap(const EventContext &ctx, const RangeKey &oldRange, RangeKey &newRange) const
Test if two ranges overlap, and adjust if needed.
Definition: CondCont.cxx:39
CondContBase::proxy
SG::DataProxy * proxy()
Return the associated DataProxy, if any.
CondContBase::insertBase
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
CondContBase::m_deps
DepSet m_deps
Definition: CondCont.h:683
CondContBase::Category::isDuplicate
static bool isDuplicate(code_t code)
Helper to test whether a code is DUPLICATE.
Definition: CondCont.cxx:228
rp
ReadCards * rp
Definition: IReadCards.cxx:26
CondContStatusCode::EXTENDED
@ EXTENDED
checker_macros.h
Define macros for attributes used to control the static checker.
python.PyAthena.obj
obj
Definition: PyAthena.py:132
CondContBase::Category::isSuccess
virtual bool isSuccess(code_t code) const override
Is code considered success?
Definition: CondCont.cxx:218
SG::DataProxy
Definition: DataProxy.h:44
CondContSingleBase::extendLastRange
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
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CondContMixedBase::entries
virtual size_t entries() const override final
Return the number of conditions objects in the container.
Definition: CondCont.cxx:943
CondContBase::delfcn
delete_function * delfcn() const
Return the deletion function for this container.
Definition: CondCont.cxx:740
CondContBase::maxSize
size_t maxSize() const
Return the maximum size of the map.
Definition: CondCont.cxx:393
CondContBase::nInserts
size_t nInserts() const
Return the number times an item was inserted into the map.
Definition: CondCont.cxx:384
CondContBase::Category
Status code category for ContCont.
Definition: CondCont.h:148
CondContSingleBase::ranges
virtual std::vector< EventIDRange > ranges() const override final
Return all IOV validity ranges defined in this container.
Definition: CondCont.cxx:775
fitman.k
k
Definition: fitman.py:528
CondContBase::KeyType::SINGLE
@ SINGLE
Either TIMESTAMP or RUNLBN, but nothing's been put in the container yet, so we don't know which one.
CondContBase::RangeKey::m_range
EventIDRange m_range
Original range object.
Definition: CondCont.h:442
CondContBase::m_keyType
std::atomic< KeyType > m_keyType
Key type of this container.
Definition: CondCont.h:663
CondContBase::print
void print() const
Dump the container to cout.
Definition: CondCont.cxx:285
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37