00001 #include "CondCore/DBCommon/interface/GenericRef.h"
00002 #include "CondCore/IOVService/interface/IOVNames.h"
00003 #include "IOVEditorImpl.h"
00004 #include "IOV.h"
00005 #include "POOLCore/Token.h"
00006 #include "StorageSvc/DbReflex.h"
00007
00008 namespace cond {
00009
00010 IOVEditorImpl::IOVEditorImpl( cond::PoolTransaction& pooldb,
00011 const std::string& token
00012 ):m_pooldb(&pooldb),m_token(token),
00013 m_isActive(false){
00014 }
00015
00016 void IOVEditorImpl::create( cond::Time_t firstSince,
00017 cond::TimeType timetype) {
00018
00019 if(!m_token.empty()){
00020
00021 throw cond::Exception("cond::IOVEditorImpl::create cannot create a IOV using an initialized Editor");
00022 }
00023
00024 if(!validTime(firstSince, timetype))
00025 throw cond::Exception("cond::IOVEditorImpl::create time not in global range");
00026
00027
00028 m_iov=cond::TypedRef<cond::IOV>(*m_pooldb,new cond::IOV);
00029 m_iov->timetype=(int)timetype;
00030 m_iov->firstsince=firstSince;
00031
00032 m_iov.markWrite(cond::IOVNames::container());
00033 m_token=m_iov.token();
00034 m_isActive=true;
00035
00036 }
00037
00038
00039
00040
00041 void IOVEditorImpl::init(){
00042 if(m_token.empty()){
00043
00044 throw cond::Exception("cond::IOVEditorImpl::init cannot init w/o token change");
00045
00046 }
00047
00048 m_iov=cond::TypedRef<cond::IOV>(*m_pooldb, m_token);
00049 m_isActive=true;
00050
00051 }
00052
00053
00054
00055 IOVEditorImpl::~IOVEditorImpl(){
00056 }
00057
00058 Time_t IOVEditorImpl::firstSince() const {
00059 return m_iov->firstsince;
00060 }
00061
00062 TimeType IOVEditorImpl::timetype() const {
00063 return m_iov->timeType();
00064 }
00065
00066
00067 bool IOVEditorImpl::validTime(cond::Time_t time, cond::TimeType timetype) const {
00068 return time>=timeTypeSpecs[timetype].beginValue && time<=timeTypeSpecs[timetype].endValue;
00069
00070 }
00071 bool IOVEditorImpl::validTime(cond::Time_t time) const {
00072 return validTime(time,timetype());
00073 }
00074
00075
00076
00077 unsigned int
00078 IOVEditorImpl::insert( cond::Time_t tillTime,
00079 const std::string& payloadToken
00080 ){
00081 if(!m_isActive) this->init();
00082
00083
00084 if(!validTime(tillTime))
00085 throw cond::Exception("cond::IOVEditorImpl::insert time not in global range");
00086
00087 if(tillTime<firstSince() ||
00088 ( !m_iov->iov.empty() && tillTime<=m_iov->iov.back().first)
00089 ) throw cond::Exception("cond::IOVEditorImpl::insert IOV not in range");
00090
00091 m_iov.markUpdate();
00092 return m_iov->add(tillTime, payloadToken);
00093
00094 }
00095
00096 void
00097 IOVEditorImpl::bulkInsert(std::vector< std::pair<cond::Time_t,std::string> >& values){
00098 if (values.empty()) return;
00099 if(!m_isActive) this->init();
00100 cond::Time_t tillTime = values.front().first;
00101
00102 if(!validTime(tillTime))
00103 throw cond::Exception("cond::IOVEditorImpl::bulkInsert first time not in global range");
00104
00105 if(!validTime(values.back().first))
00106 throw cond::Exception("cond::IOVEditorImpl::bulkInsert last time not in global range");
00107
00108 if(tillTime<firstSince() ||
00109 ( !m_iov->iov.empty() && tillTime<=m_iov->iov.back().first)
00110 ) throw cond::Exception("cond::IOVEditorImpl::bulkInsert IOV not in range");
00111
00112 m_iov->iov.insert(m_iov->iov.end(), values.begin(), values.end());
00113 m_iov.markUpdate();
00114 }
00115
00116
00117 void
00118 IOVEditorImpl::updateClosure( cond::Time_t newtillTime ){
00119 if( m_token.empty() ) throw cond::Exception("cond::IOVEditorImpl::updateClosure cannot change non-existing IOV index");
00120 if(!m_isActive) this->init();
00121 m_iov->iov.back().first=newtillTime;
00122 m_iov.markUpdate();
00123 }
00124
00125 unsigned int
00126 IOVEditorImpl::append( cond::Time_t sinceTime ,
00127 const std::string& payloadToken
00128 ){
00129 if( m_token.empty() ) {
00130 throw cond::Exception("cond::IOVEditorImpl::appendIOV cannot append to non-existing IOV index");
00131 }
00132
00133 if(!m_isActive) {
00134 this->init();
00135 }
00136
00137 if( m_iov->iov.empty() ) throw cond::Exception("cond::IOVEditorImpl::appendIOV cannot append to empty IOV index");
00138
00139
00140 if(!validTime(sinceTime))
00141 throw cond::Exception("cond::IOVEditorImpl::append time not in global range");
00142
00143 if (sinceTime<=firstSince()) throw cond::Exception("IOVEditor::append Error: since time out of range, below first since");
00144
00145
00146 if( m_iov->iov.size()>1 ){
00147
00148 cond::Time_t lastValidTill=(++m_iov->iov.rbegin())->first;
00149
00150 if( (sinceTime-1)<= lastValidTill){
00151 throw cond::Exception("IOVEditor::append Error: since time out of range: below last since");
00152 }
00153 }
00154
00155 cond::Time_t lastIOV=m_iov->iov.back().first;
00156
00157 if (lastIOV<sinceTime) lastIOV=timeTypeSpecs[timetype()].endValue;
00158 m_iov.markUpdate();
00159 m_iov->iov.back().first = sinceTime-1;
00160 return m_iov->add(lastIOV,payloadToken);
00161
00162
00163 }
00164
00165 unsigned int
00166 IOVEditorImpl::freeInsert( cond::Time_t sinceTime ,
00167 const std::string& payloadToken
00168 ){
00169 if( m_token.empty() ) {
00170 throw cond::Exception("cond::IOVEditorImpl::appendIOV cannot append to non-existing IOV index");
00171 }
00172
00173 if(!m_isActive) {
00174 this->init();
00175 }
00176
00177 if( m_iov->iov.empty() ) throw cond::Exception("cond::IOVEditorImpl::appendIOV cannot insert to empty IOV index");
00178
00179
00180 if(!validTime(sinceTime))
00181 throw cond::Exception("cond::IOVEditorImpl::freeInsert time not in global range");
00182
00183
00184
00185 if (sinceTime<firstSince()) {
00186 m_iov->iov.insert(m_iov->iov.begin(),IOV::Item(firstSince()-1,payloadToken));
00187 m_iov->firstsince=sinceTime;
00188 m_iov.markUpdate();
00189 return 0;
00190 }
00191
00192
00193 cond::Time_t tillTime;
00194 IOV::iterator p = m_iov->find(sinceTime);
00195 if (p==m_iov->iov.end()) {
00196
00197 tillTime=timeTypeSpecs[timetype()].endValue;
00198 (*(p-1)).first=sinceTime-1;
00199
00200 }
00201 else {
00202
00203 {
00204
00205 if (p==m_iov->iov.begin() ) {
00206 if (firstSince()==sinceTime)
00207 throw cond::Exception("cond::IOVEditorImpl::freeInsert sinceTime already existing");
00208 } else
00209 if ((*(p-1)).first==sinceTime-1)
00210 throw cond::Exception("cond::IOVEditorImpl::freeInsert sinceTime already existing");
00211 }
00212
00213 tillTime=(*p).first;
00214 (*p).first=sinceTime-1;
00215 p++;
00216 }
00217
00218 p = m_iov->iov.insert(p,IOV::Item(tillTime,payloadToken));
00219 m_iov.markUpdate();
00220 return p - m_iov->iov.begin();
00221
00222
00223 }
00224
00225
00226 unsigned int
00227 IOVEditorImpl::replaceInterval(cond::Time_t sinceTime,
00228 cond::Time_t tillTime,
00229 const std::string& payloadToken,
00230 bool deletePayload) {
00231
00232 static const std::string invalidToken(":");
00233
00234 if( m_token.empty() ) {
00235 throw cond::Exception("cond::IOVEditorImpl::replaceInterval cannot edit an non-existing IOV index");
00236 }
00237
00238 if(!m_isActive) {
00239 this->init();
00240 }
00241
00242 if( m_iov->iov.empty() ) throw cond::Exception("cond::IOVEditorImpl::replaceInterval cannot replace in an empty IOV index");
00243
00244
00245 if(!validTime(sinceTime)||!validTime(tillTime)||tillTime<sinceTime)
00246 throw cond::Exception("cond::IOVEditorImpl::replaceInterval times not in IOVs range");
00247
00248
00249 IOV::iterator b = m_iov->find(sinceTime);
00250 IOV::iterator e = m_iov->find(tillTime);
00251
00252
00253 if (b==m_iov->iov.end()) {
00254
00255 if (m_iov->iov.back().first<sinceTime-1)
00256 m_iov->iov.push_back(IOV::Item(sinceTime-1,invalidToken));
00257 m_iov->iov.push_back(IOV::Item(tillTime,payloadToken));
00258 m_iov.markUpdate();
00259 return m_iov->iov.size()-1;
00260 }
00261
00262 if (sinceTime<firstSince()) {
00263
00264 if (tillTime<firstSince()-1)
00265 b=m_iov->iov.insert(b,IOV::Item(firstSince()-1,invalidToken));
00266 else {
00267
00268 if (e!=m_iov->iov.end() && (*e).first==tillTime) e++;
00269 if(deletePayload) {
00270 for ( IOV::iterator p=b; p!=e; p++) {
00271 cond::GenericRef ref(*m_pooldb,(*p).second);
00272 ref.markDelete();
00273 ref.reset();
00274 }
00275 }
00276 m_iov->iov.erase(b,e);
00277 }
00278 b=m_iov->iov.begin();
00279 m_iov->iov.insert(b,IOV::Item(tillTime,payloadToken));
00280 m_iov->firstsince=sinceTime;
00281 m_iov.markUpdate();
00282 return 0;
00283 }
00284
00285 cond::Time_t newSince = (b==m_iov->iov.begin()) ? firstSince() : (*(b-1)).first+1;
00286
00287 if (sinceTime>newSince) {
00288 if ( (*b).first>tillTime) {
00289
00290 b=m_iov->iov.insert(b,IOV::Item(sinceTime-1,(*b).second));
00291 b=m_iov->iov.insert(b+1,IOV::Item(tillTime,payloadToken));
00292 m_iov.markUpdate();
00293 return b-m_iov->iov.begin();
00294 }
00295 (*b).first>sinceTime-1;
00296 b++;
00297 }
00298
00299
00300 if (e!=m_iov->iov.end() && (*e).first==tillTime) e++;
00301 if(deletePayload) {
00302 for ( IOV::iterator p=b; p!=e; p++) {
00303 cond::GenericRef ref(*m_pooldb,(*p).second);
00304 ref.markDelete();
00305 ref.reset();
00306 }
00307 }
00308 m_iov->iov.erase(b,e);
00309
00310 b = m_iov->find(sinceTime);
00311 e = m_iov->find(tillTime);
00312 if (e-b>1)
00313 throw cond::Exception("cond::IOVEditorImpl::replaceInterval vincenzo logic has a fault!!!!");
00314
00315 b = m_iov->iov.insert(b,IOV::Item(tillTime,payloadToken));
00316 m_iov.markUpdate();
00317 return b-m_iov->iov.begin();
00318
00319 }
00320
00321
00322
00323 unsigned int
00324 IOVEditorImpl::deleteEntry(cond::Time_t time,
00325 bool withPayload) {
00326 if( m_token.empty() ) {
00327 throw cond::Exception("cond::IOVEditorImpl::deleteEntry cannot delete from non-existing IOV index");
00328 }
00329
00330 if(!m_isActive) {
00331 this->init();
00332 }
00333
00334 if( m_iov->iov.empty() ) throw cond::Exception("cond::IOVEditorImpl::deleteEntry cannot delete from empty IOV index");
00335
00336
00337 if(!validTime(time)||time<firstSince())
00338 throw cond::Exception("cond::IOVEditorImpl::deleteEntry time not in IOVs range");
00339
00340 IOV::iterator p = m_iov->find(time);
00341 if (p==m_iov->iov.end())
00342 throw cond::Exception("cond::IOVEditorImpl::deleteEntry time not in IOVs range");
00343
00344 int n = p-m_iov->iov.begin();
00345 if(withPayload) {
00346 cond::GenericRef ref(*m_pooldb,(*p).second);
00347 ref.markDelete();
00348 }
00349
00350 m_iov.markUpdate();
00351 if (p==m_iov->iov.begin() )
00352 m_iov->firstsince=(*p).first+1;
00353 else
00354 (*(p-1)).first=(*p).first;
00355 m_iov->iov.erase(p);
00356
00357 return n;
00358
00359 }
00360
00361
00362 void
00363 IOVEditorImpl::deleteEntries(bool withPayload){
00364 if( m_token.empty() ) throw cond::Exception("cond::IOVEditorImpl::deleteEntries cannot delete to non-existing IOV index");
00365 if(!m_isActive) this->init();
00366 if(withPayload){
00367 std::string tokenStr;
00368 IOV::iterator payloadIt;
00369 IOV::iterator payloadItEnd=m_iov->iov.end();
00370 for(payloadIt=m_iov->iov.begin();payloadIt!=payloadItEnd;++payloadIt){
00371 tokenStr=payloadIt->second;
00372 cond::GenericRef ref(*m_pooldb,tokenStr);
00373 ref.markDelete();
00374 ref.reset();
00375 }
00376 }
00377 m_iov.markDelete();
00378 }
00379
00380 void
00381 IOVEditorImpl::import( const std::string& sourceIOVtoken ){
00382 if( !m_token.empty() ) throw cond::Exception("cond::IOVEditorImpl::import IOV index already exists, cannot import");
00383 m_iov=cond::TypedRef<cond::IOV>(*m_pooldb,sourceIOVtoken);
00384 m_iov.markWrite(cond::IOVNames::container());
00385 m_token=m_iov.token();
00386 }
00387
00388
00389 }