ATLAS Offline Software
Loading...
Searching...
No Matches
VP1Prioritiser.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Implementation of class VP1Prioritiser //
8// //
9// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10// //
11// Initial version: April 2007 //
12// //
14
17#include "VP1Base/IVP1System.h"
18#include <QTime>
19#include <QElapsedTimer>
20#include <QQueue>
21#include <QSet>
22#include <map>
23#include <cassert>
24
28
29//____________________________________________________________________
31public:
32
34 public:
40 void addTimeMeasurement(const double&);
41 double refreshtime() const { return m_timing; }
42 private:
43 double m_timing{};
44 double m_priority{};
45 const bool m_accumulator;
47 void calcPriority();
48 Imp *m_d{};
49 void removeFromPriMap();
50 QQueue<double> m_timemeasurements;
51 };
52
54 //The following map is for prioritising the order of system refreshes:
55 typedef std::multimap<double,IVP1System*> Pri2SysMap;
56 Pri2SysMap priority2sys;//This map is kept updated automatically by the SystemInfo objects.
57
58 QSet<IVP1ChannelWidget*> visiblechannels, soonvisiblechannels;
59 double soonvisbonus{};
60
61 QHash<IVP1System*,SystemInfo*> sys2info;
62
63 QElapsedTimer * stopwatch{};
65
66 void updateSysinfoWithVisibilityState(const QSet<IVP1ChannelWidget*>& channels,
68
69
70 // cppcheck-suppress uninitMemberVarNoCtor
71 std::set<IVP1System *>::const_iterator itsys;
72 // cppcheck-suppress uninitMemberVarNoCtor
73 std::set<IVP1System *>::const_iterator itsysE;
74};
75
79
80//____________________________________________________________________
82 : system(s), m_priority(117117.117),
83 m_accumulator(cw->isAccumulator()),m_vs(vs),m_d(d)
84{
85 //If another system with the same name exists already, we use that
86 //timing as a reasonable guess. Otherwise we use the average of the
87 //other channels. Failing that we use a default of 500ms.:
88 double tmp(0);
89 bool found(false);
90 QHash<IVP1System*,Imp::SystemInfo*>::iterator itE = m_d->sys2info.end();
91 for (QHash<IVP1System*,Imp::SystemInfo*>::iterator it=m_d->sys2info.begin();it!=itE;++it) {
92 if ( it.key()->name() == s->name() ) {
93 m_timing=it.value()->refreshtime();
94 found=true;
95 break;
96 }
97 tmp += m_timing=it.value()->refreshtime();
98 }
99 if (!found&&!m_d->sys2info.empty())
100 m_timing = tmp/m_d->sys2info.count();
101 else
102 m_timing=500;
103
104 calcPriority();
105}
106
107//____________________________________________________________________
112
113//____________________________________________________________________
115{
116 //Fixme: When do we get tabmanager setVisible signals? At startup? When channels are added?
117 //Fixme: Do not emit these during file loading!!
118 if (m_vs==vs)
119 return;
120 m_vs = vs;
121 calcPriority();
122}
123
124//____________________________________________________________________
126{
127 //Keep the seven latest measurements, and use a truncated mean as
128 //final estimate.
129
130 m_timemeasurements.enqueue(t);
131 if (m_timemeasurements.count()==8)
132 m_timemeasurements.dequeue();
133
134 QList<double> tmplist = m_timemeasurements;
135 std::sort(tmplist.begin(), tmplist.end());
136
137 switch(tmplist.count()) {
138 case 1: m_timing = tmplist.at(0); break;
139 case 2: m_timing = 0.5*(tmplist.at(0)+tmplist.at(1)); break;
140 case 3: m_timing = tmplist.at(1); break;
141 case 4: m_timing = 0.5*(tmplist.at(1)+tmplist.at(2)); break;
142 case 5: m_timing = (tmplist.at(1)+tmplist.at(2)+tmplist.at(3))/3.0; break;
143 case 6: m_timing = 0.5*(tmplist.at(2)+tmplist.at(3)); break;
144 case 7: m_timing = (tmplist.at(2)+tmplist.at(3)+tmplist.at(4))/3.0; break;
145 default: assert(0&&"Should never happen"); break;
146 }
147
148 calcPriority();
149}
150
151//____________________________________________________________________
153{
154 //1) Remove from m_d->priority2sys map
155
156 if (m_priority!=117117.117)
158
159 //2) Calculate new priority
160
161 //Priority is based on how long the systems take to refresh (the
162 //fastest gets refreshed first). In order to ensure that visible,
163 //soonvisible, and accumulators gets priority they get a bonus of
164 //30s, XXXms, and 100ms respectively (where XXX depends on the scenario):
165
166 m_priority = m_timing + (m_vs==VISIBLE?-30000.0:(m_vs==SOONVISIBLE?-m_d->soonvisbonus:0.0)) + (m_accumulator?-100.0:0.0);
167
168 //3) Add to m_d->priority2sys map
169
170 std::pair<double,IVP1System*> a(m_priority,system);
171 m_d->priority2sys.insert(a);
172}
173
174//____________________________________________________________________
176{
177 //Fixme: Cache itp and it (in class Imp even?)!
178 std::pair<Pri2SysMap::iterator, Pri2SysMap::iterator> itp(m_d->priority2sys.equal_range(m_priority));
179 Pri2SysMap::iterator it = itp.first;
180 for (;it!=itp.second;++it) {
181 if (it->second==system) {
182 m_d->priority2sys.erase(it);
183 break;
184 }
185 }
186 assert(it != itp.second);
187}
188
192
193//____________________________________________________________________
195 : QObject(parent), m_d(new Imp)
196{
197 m_d->prioritiser=this;
198 m_d->stopwatch = new QElapsedTimer();
199 m_d->currenttimedsystem=0;
200 m_d->soonvisbonus=0;
201}
202
203//____________________________________________________________________
205{
206 delete m_d->stopwatch;
207 delete m_d; m_d=0;
208}
209
210//___________________________________________________________________
212 Imp::Pri2SysMap::iterator itE = m_d->priority2sys.end();
213 for (Imp::Pri2SysMap::iterator it=m_d->priority2sys.begin();it!=itE;++it) {
214 if ( it->second->state()==IVP1System::ERASED &&it->second->activeState()==IVP1System::ON )
215 return it->second;
216 }
217 return 0;
218}
219
220//___________________________________________________________________
222 QList<IVP1System*> tmp;
223 Imp::Pri2SysMap::iterator itE = m_d->priority2sys.end();
224 for (Imp::Pri2SysMap::iterator it=m_d->priority2sys.begin();it!=itE;++it) {
225 if ( it->second->state()==IVP1System::REFRESHED )
226 tmp << it->second;
227 }
228 return tmp;
229}
230
231
232//___________________________________________________________________
234{
235 double tmp(0);
236 QHash<IVP1System*,Imp::SystemInfo*>::iterator itE = m_d->sys2info.end();
237 for (QHash<IVP1System*,Imp::SystemInfo*>::iterator it=m_d->sys2info.begin();it!=itE;++it) {
238 if ( it.key()->state()==IVP1System::ERASED &&it.key()->activeState()==IVP1System::ON )
239 tmp += it.value()->refreshtime();
240 }
241 return tmp;
242}
243
244//___________________________________________________________________
246{
247 assert(!m_d->currenttimedsystem);
248 m_d->stopwatch->start();
249 m_d->currenttimedsystem=s;
250 assert(m_d->sys2info.contains(s));
251 return m_d->sys2info[s]->refreshtime();
252}
253
254
255//___________________________________________________________________
257{
258 return static_cast<double>(m_d->stopwatch->elapsed());
259}
260
261//___________________________________________________________________
263{
264 assert(m_d->currenttimedsystem);
265 double timing = static_cast<double>(m_d->stopwatch->elapsed());
266 if (m_d->sys2info.contains(m_d->currenttimedsystem)) {//This check, since the corresponding channel might have become uncreated in the meantime.
267 m_d->sys2info[m_d->currenttimedsystem]->addTimeMeasurement(timing);
268 }
269 m_d->currenttimedsystem=0;
270 return timing;
271}
272
273//____________________________________________________________________
275 m_d->itsys = cw->systems().begin();
276 m_d->itsysE = cw->systems().end();
277}
278
279//___________________________________________________________________
280void VP1Prioritiser::Imp::updateSysinfoWithVisibilityState(const QSet<IVP1ChannelWidget*>& channels,
282 for(IVP1ChannelWidget*cw : channels) {
283 for (prioritiser->setupSysItr(cw);itsys!=itsysE;++itsys) {
284 assert(sys2info.contains(*itsys));
285 //if (sys2info.contains(*itsys))//This check since channel deletion might have triggered this update.
286 sys2info[*itsys]->setVisibilityState(vs);
287 }
288 }
289}
290
291//___________________________________________________________________
292void VP1Prioritiser::visibleChannelsChanged(const QSet<IVP1ChannelWidget*>&newvis,
293 const QSet<IVP1ChannelWidget*>&newsoonvis,
294 const double& soonvisbonus)
295{
296 if (m_d->visiblechannels==newvis&&m_d->soonvisiblechannels==newsoonvis&&m_d->soonvisbonus==soonvisbonus)
297 return;
298 m_d->updateSysinfoWithVisibilityState(m_d->visiblechannels,Imp::SystemInfo::NOTVISIBLE);
299 m_d->updateSysinfoWithVisibilityState(m_d->soonvisiblechannels,Imp::SystemInfo::NOTVISIBLE);
300 m_d->updateSysinfoWithVisibilityState(newvis,Imp::SystemInfo::VISIBLE);
301 m_d->updateSysinfoWithVisibilityState(newsoonvis,Imp::SystemInfo::SOONVISIBLE);
302 m_d->visiblechannels = newvis;
303 m_d->soonvisiblechannels = newsoonvis;
304 m_d->soonvisbonus = soonvisbonus;
305}
306
307//___________________________________________________________________
309{
310 bool visible = m_d->visiblechannels.contains(cw);
311 bool soonvisible = m_d->soonvisiblechannels.contains(cw);
312 assert(!(visible&&soonvisible));
313 for (setupSysItr(cw);m_d->itsys!=m_d->itsysE;++m_d->itsys) {
314 assert(!m_d->sys2info.contains(*(m_d->itsys)));
315 Imp::SystemInfo* info = new Imp::SystemInfo(*(m_d->itsys),m_d,cw,
317 m_d->sys2info.insert(*(m_d->itsys),info);
318 }
319}
320
321//___________________________________________________________________
323{
324 for (setupSysItr(cw);m_d->itsys!=m_d->itsysE;++m_d->itsys) {
325 assert(m_d->sys2info.contains(*(m_d->itsys)));
326 delete m_d->sys2info[*(m_d->itsys)];
327 m_d->sys2info.remove(*(m_d->itsys));
328 }
329 if (m_d->visiblechannels.contains(cw))
330 m_d->visiblechannels.remove(cw);
331 if (m_d->soonvisiblechannels.contains(cw))
332 m_d->soonvisiblechannels.remove(cw);
333}
static Double_t a
const std::set< IVP1System * > & systems()
void setVisibilityState(const VisibilityState &)
void addTimeMeasurement(const double &)
SystemInfo(IVP1System *, Imp *, IVP1ChannelWidget *, const VisibilityState &)
std::set< IVP1System * >::const_iterator itsys
void updateSysinfoWithVisibilityState(const QSet< IVP1ChannelWidget * > &channels, const SystemInfo::VisibilityState &vs)
VP1Prioritiser * prioritiser
QElapsedTimer * stopwatch
QSet< IVP1ChannelWidget * > soonvisiblechannels
QSet< IVP1ChannelWidget * > visiblechannels
std::set< IVP1System * >::const_iterator itsysE
QHash< IVP1System *, SystemInfo * > sys2info
IVP1System * currenttimedsystem
std::multimap< double, IVP1System * > Pri2SysMap
virtual ~VP1Prioritiser()
void setupSysItr(IVP1ChannelWidget *cw)
double estimateRemainingCalcTime() const
double elapsedTiming_Refresh()
void visibleChannelsChanged(const QSet< IVP1ChannelWidget * > &vis, const QSet< IVP1ChannelWidget * > &soonvis, const double &soonvisbonus)
IVP1System * nextErasedActiveSystemByPriority()
double endTiming_Refresh()
QList< IVP1System * > getSystemsToEraseByPriority()
VP1Prioritiser(QObject *parent)
void channelCreated(IVP1ChannelWidget *)
double beginTiming_Refresh(IVP1System *)
void channelUncreated(IVP1ChannelWidget *)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.