CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
IOVEditor.cc
Go to the documentation of this file.
6 
7 namespace cond {
8 
9  boost::shared_ptr<cond::IOVSequence> loadIOV( cond::DbSession& dbSess,
10  const std::string& iovToken ){
11  if( iovToken.empty()){
12  throw cond::Exception("IOVEditor::loadIOV Error: token is empty.");
13  }
14  boost::shared_ptr<cond::IOVSequence> iov = dbSess.getTypedObject<cond::IOVSequence>( iovToken );
15  // loading the lazy-loading Queryable vector...
16  iov->loadAll();
17  //**** temporary for the schema transition
18  if( dbSess.isOldSchema() ){
19  PoolTokenParser parser( dbSess.storage() );
20  iov->swapTokens( parser );
21  }
22  //****
23  return iov;
24  }
25 
27  const boost::shared_ptr<IOVSequence>& data,
28  bool swapOIds=false ){
29  // ***** TEMPORARY FOR TRANSITION PHASE
30  if( swapOIds && dbSess.isOldSchema() ){
31  PoolTokenWriter writer( dbSess.storage() );
32  data->swapOIds( writer );
33  }
34  // *****
35  return dbSess.storeObject( data.get(), cond::IOVNames::container());
36  }
37 
38  void updateIOV( cond::DbSession& dbSess,
39  const boost::shared_ptr<IOVSequence>& data,
40  const std::string& token ){
41  // ***** TEMPORARY FOR TRANSITION PHASE
42  if( dbSess.isOldSchema() ){
43  PoolTokenWriter writer( dbSess.storage() );
44  data->swapOIds( writer );
45  }
46  // *****
47  dbSess.updateObject( data.get(), token );
48  }
49 
50  IOVImportIterator::IOVImportIterator( boost::shared_ptr<cond::IOVProxyData>& destIov ):
51  m_sourceIov(),
52  m_destIov( destIov ),
53  m_lastSince( 0 ),
54  m_bulkSize( 0 ),
55  m_cursor(),
56  m_till()
57  {
58  }
59 
61  }
62 
64  cond::Time_t since,
65  cond::Time_t till,
66  bool outOfOrder,
67  size_t bulkSize ){
68  m_sourceIov = sourceIov;
69  const IOVSequence& siov = m_sourceIov.iov();
70  cond::Time_t dsince = std::max(since, siov.firstSince());
71  IOVSequence::const_iterator ifirstTill = siov.find(dsince);
72  IOVSequence::const_iterator isecondTill = siov.find(till);
73  if( isecondTill != siov.iovs().end() ) isecondTill++;
74 
75  if (ifirstTill==isecondTill)
76  throw cond::Exception("IOVImportIterator::setUp Error: empty input range");
77 
78  IOVSequence& diov = *m_destIov->data;
79  if ( diov.iovs().empty()) ; // do not waist time
80  else if (outOfOrder) {
81  for( IOVSequence::const_iterator it=ifirstTill;
82  it!=isecondTill; ++it)
83  if (diov.exist(it->sinceTime()))
84  throw cond::Exception("IOVImportIterator::setUp Error: since time already exists");
85  } else if (dsince <= diov.iovs().back().sinceTime()) {
86  std::ostringstream errStr;
87  errStr << "IOVImportIterator::setUp Error: trying to append a since time " << dsince
88  << " which is not larger than last since " << diov.iovs().back().sinceTime();
89  throw cond::Exception(errStr.str());
90  }
91 
92  m_lastSince = dsince;
93  m_cursor = ifirstTill;
94  m_till = isecondTill;
95  m_bulkSize = bulkSize;
96  }
97 
99  const std::string& sourceIovToken,
100  cond::Time_t since,
101  cond::Time_t till,
102  bool outOfOrder,
103  size_t bulkSize ){
104  IOVProxy sourceIov( sourceSess, sourceIovToken );
105  setUp( sourceIov, since, till, outOfOrder, bulkSize );
106  }
107 
109  size_t bulkSize ){
110 
111  m_sourceIov = sourceIov;
112  const IOVSequence& siov = m_sourceIov.iov();
113  cond::Time_t dsince = siov.firstSince();
114 
115  IOVSequence::const_iterator ifirstTill = siov.iovs().begin();
116  IOVSequence::const_iterator isecondTill = siov.iovs().end();
117 
118  IOVSequence& diov = *m_destIov->data;
119  if (!diov.iovs().empty()) { // do not waist time
120  if (dsince <= diov.iovs().back().sinceTime()) {
121  std::ostringstream errStr;
122  errStr << "IOVImportIterator::setUp Error: trying to append a since time " << dsince
123  << " which is not larger than last since " << diov.iovs().back().sinceTime();
124  throw cond::Exception(errStr.str());
125  }
126  }
127 
128  m_lastSince = dsince;
129  m_cursor = ifirstTill;
130  m_till = isecondTill;
131  m_bulkSize = bulkSize;
132  }
133 
135  const std::string& sourceIovToken,
136  size_t bulkSize ){
137  IOVProxy sourceIov( sourceSess, sourceIovToken );
138  setUp( sourceIov, bulkSize );
139  }
140 
142  return m_cursor != m_till;
143  }
144 
146  size_t i = 0;
147  boost::shared_ptr<IOVSequence>& diov = m_destIov->data;
148  for( ; i<m_bulkSize && m_cursor != m_till; ++i, ++m_cursor, m_lastSince=m_cursor->sinceTime() ){
149  std::string newPtoken = m_destIov->dbSession.importObject( m_sourceIov.db(),m_cursor->token());
150  ora::OId poid;
151  poid.fromString( newPtoken );
152  ora::Container cont = m_destIov->dbSession.storage().containerHandle( poid.containerId() );
153  diov->add(m_lastSince, newPtoken, cont.className());
154  }
155  if( m_cursor == m_till ) diov->stamp(cond::userInfo(),false);
156  updateIOV( m_destIov->dbSession, diov, m_destIov->token );
157  return i;
158  }
159 
161  size_t total = 0;
162  while( hasMoreElements() ){
163  total += importMoreElements();
164  }
165  return total;
166  }
167 
169  m_isLoaded(false),
170  m_iov(){
171  }
172 
174 
176  m_isLoaded(false),
177  m_iov( new IOVProxyData( dbSess ) ){
178  }
179 
181  const std::string& token ):
182  m_isLoaded(false),
183  m_iov( new IOVProxyData( dbSess, token )){
184  }
185 
187  m_isLoaded( rhs.m_isLoaded ),
188  m_iov( rhs.m_iov ){
189  }
190 
192  m_isLoaded = rhs.m_isLoaded;
193  m_iov = rhs.m_iov;
194  return *this;
195  }
196 
198  m_iov->refresh();
199  m_isLoaded = true;
200  }
201 
202  void IOVEditor::load( const std::string& token ){
203  m_iov->token = token;
204  m_iov->refresh();
205  m_isLoaded = true;
206  }
207 
208  void IOVEditor::debugInfo(std::ostream & co) const {
209  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
210  co << "IOVEditor: ";
211  co << "db " << m_iov->dbSession.connectionString();
212  if(m_iov->token.empty()) {
213  co << " no token"; return;
214  }
215  if (!m_iov->data.get() ) {
216  co << " no iov for token " << m_iov->token;
217  return;
218  }
219  co << " iov token " << m_iov->token;
220  co << "\nStamp: " << iov->comment()
221  << "; time " << iov->timestamp()
222  << "; revision " << iov->revision();
223  co <<". TimeType " << cond::timeTypeSpecs[ iov->timeType()].name;
224  if( iov->iovs().empty() )
225  co << ". empty";
226  else
227  co << ". size " << iov->iovs().size()
228  << "; last since " << iov->iovs().back().sinceTime();
229  }
230 
232  std::ostringstream out;
233  out << "Error in ";
234  debugInfo(out);
235  out << "\n" << message;
236  throw cond::Exception(out.str());
237  }
238 
240  cond::Time_t time) const {
241  std::ostringstream out;
242  out << "Error in ";
243  debugInfo(out);
244  out << "\n" << message << " for time: " << time;
245  throw cond::Exception(out.str());
246  }
247 
248 
250  bool ret = false;
251  cond::IOVSchemaUtility schemaUtil( m_iov->dbSession );
252  if( !schemaUtil.existsIOVContainer() ){
253  schemaUtil.createIOVContainer();
254  ret = true;
255  }
256  return ret;
257  }
258 
259  // create empty default sequence
261  m_iov->data.reset( new cond::IOVSequence(timetype) );
262  m_iov->token = insertIOV( m_iov->dbSession, m_iov->data );
263  m_isLoaded=true;
264  return m_iov->token;
265  }
266 
268  cond::Time_t lastTill,
269  const std::string& metadata ) {
270  m_iov->data.reset( new cond::IOVSequence((int)timetype,lastTill, metadata) );
271  m_iov->token = insertIOV( m_iov->dbSession, m_iov->data );
272  m_isLoaded=true;
273  return m_iov->token;
274  }
275 
276  // ####### TO BE REOMOVED ONLY USED IN TESTS
278  m_iov->data.reset( new cond::IOVSequence((int)timetype,lastTill, std::string(" ")) );
279  m_iov->token = insertIOV( m_iov->dbSession, m_iov->data );
280  m_isLoaded=true;
281  return m_iov->token;
282  }
283 
285  cond::TimeType timetype) const {
287 
288  }
289 
291  return validTime(time,m_iov->data->timeType());
292  }
293 
294 
295 
296  unsigned int
298  const std::string& payloadToken ){
299  if( !m_isLoaded ){
300  reload();
301  }
302  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
303  if( iov->iovs().empty() )
304  reportError("cond::IOVEditor::insert cannot inser into empty IOV sequence",tillTime);
305 
306  if(!validTime(tillTime))
307  reportError("cond::IOVEditor::insert time not in global range",tillTime);
308 
309  if(tillTime<=iov->lastTill() )
310  reportError("cond::IOVEditor::insert IOV not in range",tillTime);
311 
312  cond::Time_t newSince=iov->lastTill()+1;
313  std::string payloadClassName = m_iov->dbSession.classNameForItem( payloadToken );
314  unsigned int ret = iov->add(newSince, payloadToken, payloadClassName);
315  iov->updateLastTill(tillTime);
316  updateIOV( m_iov->dbSession, iov, m_iov->token );
317  return ret;
318  }
319 
320  void
321  IOVEditor::bulkAppend(std::vector< std::pair<cond::Time_t, std::string > >& values){
322  if (values.empty()) return;
323  if( !m_isLoaded ){
324  reload();
325  }
326  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
327  cond::Time_t firstTime = values.front().first;
328  cond::Time_t lastTime = values.back().first;
329  if(!validTime(firstTime))
330  reportError("cond::IOVEditor::bulkInsert first time not in global range",firstTime);
331 
332  if(!validTime(lastTime))
333  reportError("cond::IOVEditor::bulkInsert last time not in global range",lastTime);
334 
335  if(lastTime>= iov->lastTill() ||
336  ( !iov->iovs().empty() && firstTime<=iov->iovs().back().sinceTime())
337  )
338  reportError("cond::IOVEditor::bulkInsert IOV not in range",firstTime);
339 
340  for(std::vector< std::pair<cond::Time_t,std::string> >::const_iterator it=values.begin(); it!=values.end(); ++it){
341  std::string payloadClassName = m_iov->dbSession.classNameForItem( it->second );
342  iov->add(it->first,it->second,payloadClassName );
343  }
344  updateIOV( m_iov->dbSession, iov, m_iov->token );
345  }
346 
347  void
348  IOVEditor::bulkAppend(std::vector< cond::IOVElement >& values){
349  if (values.empty()) return;
350  if( !m_isLoaded ){
351  reload();
352  }
353  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
354  cond::Time_t firstTime = values.front().sinceTime();
355  cond::Time_t lastTime = values.back().sinceTime();
356  if(!validTime(firstTime))
357  reportError("cond::IOVEditor::bulkInsert first time not in global range",firstTime);
358 
359  if(!validTime(lastTime))
360  reportError("cond::IOVEditor::bulkInsert last time not in global range",lastTime);
361 
362  if(lastTime>=iov->lastTill() ||
363  ( !iov->iovs().empty() && firstTime<=iov->iovs().back().sinceTime())
364  ) reportError("cond::IOVEditor::bulkInsert IOV not in range",firstTime);
365 
366  for(std::vector< cond::IOVElement >::const_iterator it=values.begin(); it!=values.end(); ++it){
367  std::string payloadClassName = m_iov->dbSession.classNameForItem( it->token() );
368  iov->add(it->sinceTime(),it->token(),payloadClassName );
369  }
370 
371  updateIOV( m_iov->dbSession, iov, m_iov->token );
372  }
373 
374  void
375  IOVEditor::stamp( std::string const & icomment,
376  bool append) {
377  if( !m_isLoaded ){
378  reload();
379  }
380  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
381  iov->stamp(icomment, append);
382  updateIOV( m_iov->dbSession, iov, m_iov->token );
383  }
384 
385  void IOVEditor::editMetadata( std::string const & metadata,
386  bool append ){
387  if( !m_isLoaded ){
388  reload();
389  }
390  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
391  iov->updateMetadata( metadata, append);
392  updateIOV( m_iov->dbSession, iov, m_iov->token );
393  }
394 
396  if( !m_isLoaded ){
397  reload();
398  }
399  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
400  iov->setScope( scope );
401  updateIOV( m_iov->dbSession, iov, m_iov->token );
402  }
403 
404  void
406  if( m_iov->token.empty() ) reportError("cond::IOVEditor::updateClosure cannot change non-existing IOV index");
407  if( !m_isLoaded ){
408  reload();
409  }
410  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
411  iov->updateLastTill(newtillTime);
412  updateIOV( m_iov->dbSession, iov, m_iov->token );
413  }
414 
415  unsigned int
417  const std::string& payloadToken ){
418  if( m_iov->token.empty() ) {
419  reportError("cond::IOVEditor::appendIOV cannot append to non-existing IOV index");
420  }
421 
422  if( !m_isLoaded ){
423  reload();
424  }
425  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
426 
427  if(!validTime(sinceTime))
428  reportError("cond::IOVEditor::append time not in global range",sinceTime);
429 
430  if( !iov->iovs().empty() ){
431  //range check in case
432  cond::Time_t lastValidSince=iov->iovs().back().sinceTime();
433  if( sinceTime<= lastValidSince){
434  std::ostringstream errStr;
435  errStr << "IOVEditor::append Error: trying to append a since time " << lastValidSince
436  << " which is not larger than last since";
437  reportError(errStr.str(), sinceTime);
438  }
439  }
440 
441  // does it make sense? (in case of mixed till and since insertions...)
442  if (iov->lastTill()<=sinceTime) iov->updateLastTill( timeTypeSpecs[iov->timeType()].endValue );
443  std::string payloadClassName = m_iov->dbSession.classNameForItem( payloadToken );
444  unsigned int ret = iov->add(sinceTime,payloadToken, payloadClassName );
445  updateIOV( m_iov->dbSession, iov, m_iov->token );
446  return ret;
447  }
448 
449 
450  unsigned int
452  const std::string& payloadToken ){
453  if( m_iov->token.empty() ) {
454  reportError("cond::IOVEditor::freeInsert cannot append to non-existing IOV index");
455  }
456 
457  if( !m_isLoaded ){
458  reload();
459  }
460  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
461 
462  // if( m_iov->data->iov.empty() ) reportError("cond::IOVEditor::freeInsert cannot insert to empty IOV index");
463 
464 
465  if(!validTime(sinceTime))
466  reportError("cond::IOVEditor::freeInsert time not in global range",sinceTime);
467 
468 
469  // we do not support multiple iov with identical since...
470  if (m_iov->data->exist(sinceTime))
471  reportError("cond::IOVEditor::freeInsert sinceTime already existing",sinceTime);
472 
473 
474 
475  // does it make sense? (in case of mixed till and since insertions...)
476  if (iov->lastTill()<sinceTime) iov->updateLastTill( timeTypeSpecs[iov->timeType()].endValue );
477  std::string payloadClassName = m_iov->dbSession.classNameForItem( payloadToken );
478  unsigned int ret = iov->add(sinceTime,payloadToken, payloadClassName );
479  updateIOV( m_iov->dbSession, iov, m_iov->token );
480  return ret;
481  }
482 
483 
484  // remove last entry
485  unsigned int IOVEditor::truncate(bool withPayload) {
486  if( m_iov->token.empty() ) reportError("cond::IOVEditor::truncate cannot delete to non-existing IOV sequence");
487  if( !m_isLoaded ){
488  reload();
489  }
490  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
491  if (iov->piovs().empty()) return 0;
492  if(withPayload){
493  std::string tokenStr = iov->piovs().back().token();
494  m_iov->dbSession.deleteObject( tokenStr );
495  }
496  unsigned int ret = iov->truncate();
497  updateIOV( m_iov->dbSession, iov, m_iov->token );
498  return ret;
499 
500  }
501 
502 
503  void
504  IOVEditor::deleteEntries(bool withPayload){
505  if( m_iov->token.empty() ) reportError("cond::IOVEditor::deleteEntries cannot delete to non-existing IOV sequence");
506  if( !m_isLoaded ){
507  reload();
508  }
509  boost::shared_ptr<IOVSequence>& iov = m_iov->data;
510  if(withPayload){
511  std::string tokenStr;
512  IOVSequence::const_iterator payloadIt;
513  IOVSequence::const_iterator payloadItEnd=iov->piovs().end();
514  for(payloadIt=iov->piovs().begin();payloadIt!=payloadItEnd;++payloadIt){
515  tokenStr=payloadIt->token();
516  m_iov->dbSession.deleteObject( tokenStr );
517  }
518  }
519  m_iov->dbSession.deleteObject( m_iov->token );
520  iov->piovs().clear();
521  }
522 
523  size_t IOVEditor::import( cond::DbSession& sourceSess,
524  const std::string& sourceIovToken ){
525  boost::shared_ptr<IOVImportIterator> importer = importIterator();
526  importer->setUp( sourceSess, sourceIovToken );
527  return importer->importAll();
528  }
529 
530  boost::shared_ptr<IOVImportIterator>
532  if( !m_isLoaded ){
533  reload();
534  }
535  return boost::shared_ptr<IOVImportIterator>( new IOVImportIterator( m_iov ));
536  }
537 
539  return m_iov->data->timeType();
540  }
541 
542  std::string const & IOVEditor::token() const {
543  return m_iov->token;
544  }
545 
547  return IOVProxy( m_iov );
548  }
549 
550 }
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:22
int i
Definition: DBlmapReader.cc:9
std::string create(cond::TimeType timetype)
Definition: IOVEditor.cc:260
void debugInfo(std::ostream &co) const
Definition: IOVEditor.cc:208
IOVSequence const & iov() const
Definition: IOVProxy.cc:276
void load(const std::string &token)
Definition: IOVEditor.cc:202
void reportError(std::string message) const
Definition: IOVEditor.cc:231
tuple cont
load Luminosity info ##
Definition: generateEDF.py:622
IOVEditor & operator=(const IOVEditor &rhs)
Definition: IOVEditor.cc:191
Time_t beginValue
Definition: Time.h:45
const_iterator find(cond::Time_t time) const
Definition: IOVSequence.cc:110
void updateIOV(cond::DbSession &dbSess, const boost::shared_ptr< IOVSequence > &data, const std::string &token)
Definition: IOVEditor.cc:38
bool validTime(cond::Time_t time, cond::TimeType timetype) const
Definition: IOVEditor.cc:284
cond::Time_t firstSince() const
Definition: IOVSequence.h:63
Container const & iovs() const
Definition: IOVSequence.cc:76
Definition: OId.h:8
size_t import(cond::DbSession &sourceSess, const std::string &sourceIovToken)
Definition: IOVEditor.cc:523
std::string const & token() const
Definition: IOVEditor.cc:542
boost::shared_ptr< cond::IOVSequence > loadIOV(cond::DbSession &dbSess, const std::string &iovToken)
Definition: IOVEditor.cc:9
void setScope(cond::IOVSequence::ScopeType scope)
set the scope
Definition: IOVEditor.cc:395
Container::const_iterator const_iterator
Definition: IOVSequence.h:29
unsigned int freeInsert(cond::Time_t sinceTime, const std::string &payloadToken)
insert a payload with known since in any position
Definition: IOVEditor.cc:451
cond::IOVProxy m_sourceIov
Definition: IOVEditor.h:48
IOVSequence::const_iterator m_cursor
Definition: IOVEditor.h:52
TimeType
Definition: Time.h:21
IOVImportIterator(boost::shared_ptr< cond::IOVProxyData > &destIov)
Definition: IOVEditor.cc:50
const std::string & className()
Definition: Container.cc:75
unsigned int truncate(bool withPayload=false)
Definition: IOVEditor.cc:485
bool exist(cond::Time_t time) const
Definition: IOVSequence.cc:127
unsigned long long Time_t
Definition: Time.h:16
TimeType timetype() const
Definition: IOVEditor.cc:538
void loadAll() const
Definition: IOVSequence.cc:69
bool firstTime
Definition: QTestHandle.cc:16
tuple iov
Definition: o2o.py:307
int containerId() const
Definition: OId.cc:50
std::string storeObject(const T *object, const std::string &containerName)
Definition: DbSession.h:132
tuple out
Definition: dbtoconf.py:99
unsigned int insert(cond::Time_t tillTime, const std::string &payloadToken)
Assign a payload with till time. Returns the payload index in the iov sequence.
Definition: IOVEditor.cc:297
bool createIOVContainerIfNecessary()
Definition: IOVEditor.cc:249
IOVSequence::const_iterator m_till
Definition: IOVEditor.h:53
cond::IOVProxy proxy() const
Definition: IOVEditor.cc:546
bool isOldSchema()
Definition: DbSession.cc:230
void updateClosure(cond::Time_t newtillTime)
Update the closure of the iov sequence.
Definition: IOVEditor.cc:405
unsigned int append(cond::Time_t sinceTime, const std::string &payloadToken)
Definition: IOVEditor.cc:416
cond::Time_t m_lastSince
Definition: IOVEditor.h:50
std::string name
Definition: Time.h:43
std::string insertIOV(cond::DbSession &dbSess, const boost::shared_ptr< IOVSequence > &data, bool swapOIds=false)
Definition: IOVEditor.cc:26
static std::string container()
Definition: IOVNames.h:7
virtual ~IOVImportIterator()
Definition: IOVEditor.cc:60
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
void bulkAppend(std::vector< std::pair< cond::Time_t, std::string > > &values)
Bulk append of iov chunck.
Definition: IOVEditor.cc:321
void stamp(std::string const &icomment, bool append=false)
Definition: IOVEditor.cc:375
std::string userInfo()
Definition: IOVInfo.cc:9
void deleteEntries(bool withPayload=false)
Definition: IOVEditor.cc:504
bool createIOVContainer()
create iov tables
volatile std::atomic< bool > shutdown_flag false
Time_t endValue
Definition: Time.h:46
boost::shared_ptr< IOVImportIterator > importIterator()
Definition: IOVEditor.cc:531
bool fromString(const std::string &s)
Definition: OId.cc:64
bool updateObject(const T *object, const std::string &objectId)
Definition: DbSession.h:143
boost::shared_ptr< T > getTypedObject(const std::string &objectId)
Definition: DbSession.h:126
ora::Database & storage()
Definition: DbSession.cc:215
void setUp(cond::IOVProxy &sourceIov, cond::Time_t since, cond::Time_t till, bool outOfOrder, size_t bulkSize=1)
Definition: IOVEditor.cc:63
boost::shared_ptr< cond::IOVProxyData > m_destIov
Definition: IOVEditor.h:49
boost::shared_ptr< cond::IOVProxyData > m_iov
Definition: IOVEditor.h:147
~IOVEditor()
Destructor.
Definition: IOVEditor.cc:173
void editMetadata(std::string const &metadata, bool append=false)
edit metadata
Definition: IOVEditor.cc:385
DbSession & db()
Definition: IOVProxy.cc:312