17#include "GaudiKernel/EventContext.h"
18#include "GaudiKernel/ServiceHandle.h"
20#include <unordered_set>
30#define USE_ASYNC_TASK 0
50 {
parent(),
"RingSize", 100,
51 "Number of previous events for which to remember IOV history." };
56 {
parent(),
"CleanDelay", 100,
57 "Number of events after adding a conditions object we try to clean its container." };
61 {
parent(),
"LookAhead", 10,
62 "Maximum number of events to consolodate together when cleaning." };
68 {
parent(),
"Async",
false,
69 "If true, run cleaning asynchronously in an MT job." };
76 {
parent(),
"RCUSvc",
"Athena::RCUSvc",
85class DelayedConditionsCleanerTask
96 DelayedConditionsCleanerTask (DelayedConditionsCleanerSvc& cleaner,
97 std::vector<DelayedConditionsCleanerSvc::CondContInfo*>&& cis,
98 DelayedConditionsCleanerSvc::twoKeys_t&& keys);
103 tbb::task* execute()
override;
108 DelayedConditionsCleanerSvc& m_cleaner;
111 std::vector<DelayedConditionsCleanerSvc::CondContInfo*> m_cis;
114 DelayedConditionsCleanerSvc::twoKeys_t m_keys;
124DelayedConditionsCleanerTask::DelayedConditionsCleanerTask
126 std::vector<DelayedConditionsCleanerSvc::CondContInfo*>&& cis,
138tbb::task* DelayedConditionsCleanerTask::execute()
141 m_cleaner.cleanContainers (std::move (m_cis), std::move (m_keys));
144 --m_cleaner.m_cleanTasks;
157 : base_class (name, svc),
173 size_t nslots =
m_props->m_rcu->getNumSlots();
177 return StatusCode::SUCCESS;
196 EventContext::ContextID_t slot = ctx.slot();
197 if (slot != EventContext::INVALID_CONTEXT_ID) {
206 return StatusCode::SUCCESS;
210 std::vector<CondContInfo*> ci_vec;
214 if (!
m_work.empty() &&
m_work.top().m_evt <= ctx.evt()) {
216 size_t sz =
m_work.size();
226 case KeyType::SINGLE:
228 case KeyType::RUNLBN:
230 case KeyType::TIMESTAMP:
231 ci_vec.push_back (ci);
243 if (!ci_vec.empty()) {
247 return StatusCode::SUCCESS;
261 CCInfoMap_t::iterator it =
m_ccinfo.find (&cc);
266 EventContext::ContextEvt_t evt = ctx.evt();
268 return StatusCode::SUCCESS;
281 return StatusCode::SUCCESS;
292 std::vector<const CondContInfo*> infos;
294 infos.push_back (&p.second);
298 { return a->m_cc.id().key() < b->m_cc.id().key(); });
302 ci->m_cc.id().key().c_str(),
304 ci->m_cc.maxSize()) );
305 den = std::max (ci->m_nClean, 1lu);
308 static_cast<float> (ci->m_nRemoved) / den,
311 ci->m_removed2plus) );
314 return StatusCode::SUCCESS;
331 std::priority_queue<QueueItem> tmp;
340 return StatusCode::SUCCESS;
348 std::vector<key_type> runLBKeys=runLBRing.
getKeysDedup();
365 for (
auto& keys :
result ) {
368 keys.resize (end - keys.begin());
393 cis.resize (pos - cis.begin());
395 if (allowAsync &&
m_props->m_async) {
403 tbb::task* t =
new (tbb::task::allocate_root())
405 std::move (twoKeys));
406 tbb::task::enqueue (*t);
435 std::vector<CondContInfo*> toclean = std::move (cis);
436 std::unordered_set<CondContInfo*> cleaned (toclean.begin(), toclean.end());
437 while (!toclean.empty()) {
438 std::vector<CondContInfo*> newclean;
443 CCInfoMap_t::iterator it =
m_ccinfo.find (dep);
447 if (cleaned.insert (ci_dep).second) {
448 newclean.push_back (ci_dep);
454 toclean = std::move (newclean);
471 size_t n = ci->
m_cc.
trim (twoKeys[0],twoKeys[1]);
501 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
pimpl-style holder for component properties.
Hold mappings of ranges to condition objects.
Clean conditions containers after a delay.
read-copy-update (RCU) style synchronization for Athena.
DelayedConditionsCleanerSvc * parent()
AthProperties(DelayedConditionsCleanerSvc *parent)
bool m_async
Property: If true, run cleaning asynchronously in an MT job.
Gaudi::Property< size_t > m_cleanDelay
Property: Number of events after adding a conditions object we try to clean its container.
ServiceHandle< Athena::IRCUSvc > m_rcu
Property: RCU Service.
DelayedConditionsCleanerSvcProps(DelayedConditionsCleanerSvc *parent)
Gaudi::Property< size_t > m_ringSize
Property: Number of previous events for which to remember IOV history.
Gaudi::Property< size_t > m_lookAhead
Property: Maximum number of events to consolodate together when cleaning.
Information that we maintain about each conditions container.
size_t m_removed2plus
Number of times two or more objects were removed.
size_t m_removed1
Number of times exactly 1 object was removed.
size_t m_removed0
Number of times exactly 0 objects were removed.
size_t m_nClean
Number of times cleaning was attempted.
CondContBase & m_cc
The conditions container.
size_t m_nRemoved
Total number of objects removed by cleaning.
Clean conditions containers after a delay.
DelayedConditionsCleanerSvc(const std::string &name, ISvcLocator *svc)
Standard Gaudi constructor.
std::priority_queue< QueueItem > m_work
Priority queue of pending cleaning requests.
size_t m_nEvents
Priority queue statistics.
friend class DelayedConditionsCleanerTask
twoKeys_t getKeys(const Ring &runLBRing, const Ring &TSRing) const
virtual StatusCode condObjAdded(const EventContext &ctx, CondContBase &cc) override
Called after a conditions object has been added.
virtual StatusCode initialize() override
Standard Gaudi initialize method.
Ring m_runlbn
Two ring buffers for recent IOV keys, one for run+LBN and one for timestamp.
std::vector< key_type > m_slotTimestamp
virtual StatusCode event(const EventContext &ctx, bool allowAsync) override
Called at the start of each event.
void scheduleClean(std::vector< CondContInfo * > &&cis, twoKeys_t &&twoKeys, bool allowAsync)
Do cleaning for a set of containers.
std::unique_ptr< DelayedConditionsCleanerSvcProps > m_props
Component properties.
CxxUtils::Ring< key_type > Ring
Ring buffer holding most recent IOV keys of a given type.
CondContBase::key_type key_type
Packed key type.
std::lock_guard< mutex_t > lock_t
std::atomic< int > m_cleanTasks
Number of active asynchronous cleaning tasks.
virtual StatusCode reset() override
Clear the internal state of the service.
std::array< std::vector< key_type >, 2 > twoKeys_t
void cleanContainers(std::vector< CondContInfo * > &&cis, twoKeys_t &&twoKeys)
Clean a set of containers.
bool cleanContainer(CondContInfo *ci, const twoKeys_t &keys) const
Clean a single container.
std::vector< key_type > m_slotLBN
IOV keys currently in use for each slot.
virtual StatusCode finalize() override
Standard Gaudi finalize method.
virtual StatusCode printStats() const override
Print some statistics about the garbage collection.
~DelayedConditionsCleanerSvc()
Standard destructor.
Base class for all conditions containers.
static key_type keyFromTimestamp(const EventIDBase &b)
Make a timestamp key from an EventIDBase.
static key_type keyFromRunLBN(const EventIDBase &b)
Make a run+lbn key from an EventIDBase.
KeyType keyType() const
Return the key type for this container.
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.
std::vector< CondContBase * > getDeps()
Return the list of conditions containers that depend on this one.
std::vector< T > getKeysDedup() const
Return a copy of keys in the buffer.
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
std::string strformat(const char *fmt,...)
return a std::string according to a format fmt and varargs
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.