File indexing completed on 2024-10-17 04:58:07
0001 #include <memory>
0002
0003 #include "CondCore/CondDB/interface/IOVProxy.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "SessionImpl.h"
0006
0007 namespace cond {
0008
0009 namespace persistency {
0010
0011
0012 struct IOVComp {
0013 bool operator()(const cond::Time_t& x, const cond::Time_t& y) { return (x < y); }
0014
0015 bool operator()(const cond::Time_t& x, const std::tuple<cond::Time_t, cond::Hash>& y) {
0016 return (x < std::get<0>(y));
0017 }
0018 };
0019
0020
0021 template <typename T>
0022 typename std::vector<T>::const_iterator search(const cond::Time_t& val, const std::vector<T>& container) {
0023 if (container.empty())
0024 return container.end();
0025 auto p = std::upper_bound(container.begin(), container.end(), val, IOVComp());
0026 return (p != container.begin()) ? p - 1 : container.end();
0027 }
0028
0029 IOVArray::Iterator::Iterator() : m_current(), m_parent(nullptr) {}
0030
0031 IOVArray::Iterator::Iterator(IOVContainer::const_iterator current, const IOVArray* parent)
0032 : m_current(current), m_parent(parent) {}
0033
0034 IOVArray::Iterator::Iterator(const Iterator& rhs) : m_current(rhs.m_current), m_parent(rhs.m_parent) {}
0035
0036 IOVArray::Iterator& IOVArray::Iterator::operator=(const Iterator& rhs) {
0037 if (this != &rhs) {
0038 m_current = rhs.m_current;
0039 m_parent = rhs.m_parent;
0040 }
0041 return *this;
0042 }
0043
0044 cond::Iov_t IOVArray::Iterator::operator*() {
0045 cond::Iov_t retVal;
0046 retVal.since = std::get<0>(*m_current);
0047 auto next = m_current;
0048 next++;
0049 if (next == m_parent->m_array->end()) {
0050 retVal.till = cond::time::MAX_VAL;
0051 } else {
0052 retVal.till = cond::time::tillTimeFromNextSince(std::get<0>(*next), m_parent->m_tagInfo.timeType);
0053 }
0054
0055 if (retVal.till > m_parent->m_tagInfo.endOfValidity) {
0056 retVal.till = m_parent->m_tagInfo.endOfValidity;
0057 }
0058 retVal.payloadId = std::get<1>(*m_current);
0059
0060 return retVal;
0061 }
0062
0063 IOVArray::Iterator& IOVArray::Iterator::operator++() {
0064 m_current++;
0065 return *this;
0066 }
0067
0068 IOVArray::Iterator IOVArray::Iterator::operator++(int) {
0069 Iterator tmp(*this);
0070 operator++();
0071 return tmp;
0072 }
0073
0074 bool IOVArray::Iterator::operator==(const Iterator& rhs) const {
0075 if (m_current != rhs.m_current)
0076 return false;
0077 if (m_parent != rhs.m_parent)
0078 return false;
0079 return true;
0080 }
0081
0082 bool IOVArray::Iterator::operator!=(const Iterator& rhs) const { return !operator==(rhs); }
0083
0084 IOVArray::IOVArray() : m_array(new IOVContainer) {}
0085
0086 IOVArray::IOVArray(const IOVArray& rhs) : m_array(), m_tagInfo(rhs.m_tagInfo) {
0087 m_array = std::make_unique<IOVContainer>(*rhs.m_array);
0088 }
0089
0090 IOVArray& IOVArray::operator=(const IOVArray& rhs) {
0091 m_array = std::make_unique<IOVContainer>(*rhs.m_array);
0092 m_tagInfo = rhs.m_tagInfo;
0093 return *this;
0094 }
0095
0096 const cond::Tag_t& IOVArray::tagInfo() const { return m_tagInfo; }
0097
0098 IOVArray::Iterator IOVArray::begin() const { return Iterator(m_array->begin(), this); }
0099
0100 IOVArray::Iterator IOVArray::end() const { return Iterator(m_array->end(), this); }
0101
0102 IOVArray::Iterator IOVArray::find(cond::Time_t time) const { return Iterator(search(time, *m_array), this); }
0103
0104 size_t IOVArray::size() const { return m_array->size(); }
0105
0106
0107 bool IOVArray::isEmpty() const { return m_array->empty(); }
0108
0109
0110
0111 class IOVProxyData {
0112 public:
0113 IOVProxyData() : iovSequence() {}
0114
0115
0116 cond::Tag_t tagInfo;
0117
0118 boost::posix_time::ptime snapshotTime;
0119 cond::Time_t groupLowerIov = cond::time::MAX_VAL;
0120 cond::Time_t groupHigherIov = cond::time::MIN_VAL;
0121 bool cacheInitialized = false;
0122 std::vector<cond::Time_t> sinceGroups;
0123 IOVContainer iovSequence;
0124
0125 size_t numberOfQueries = 0;
0126 };
0127
0128 IOVProxy::IOVProxy() : m_data(), m_session() {}
0129
0130 IOVProxy::IOVProxy(const std::shared_ptr<SessionImpl>& session) : m_data(new IOVProxyData), m_session(session) {}
0131
0132 IOVProxy::IOVProxy(const IOVProxy& rhs) : m_data(rhs.m_data), m_session(rhs.m_session) {}
0133
0134 IOVProxy& IOVProxy::operator=(const IOVProxy& rhs) {
0135 m_data = rhs.m_data;
0136 m_session = rhs.m_session;
0137 return *this;
0138 }
0139
0140 void IOVProxy::load(const std::string& tagName) {
0141 boost::posix_time::ptime notime;
0142 load(tagName, notime);
0143 }
0144
0145 void IOVProxy::load(const std::string& tagName, const boost::posix_time::ptime& snapshotTime) {
0146 if (!m_data.get())
0147 return;
0148
0149
0150 reset();
0151
0152 checkTransaction("IOVProxyNew::load");
0153
0154 int dummy;
0155 if (!m_session->iovSchema().tagTable().select(tagName,
0156 m_data->tagInfo.timeType,
0157 m_data->tagInfo.payloadType,
0158 m_data->tagInfo.synchronizationType,
0159 m_data->tagInfo.endOfValidity,
0160 m_data->tagInfo.lastValidatedTime,
0161 dummy)) {
0162 throwException("Tag \"" + tagName + "\" has not been found in the database.", "IOVProxy::load");
0163 }
0164 m_data->tagInfo.name = tagName;
0165 m_data->snapshotTime = snapshotTime;
0166 }
0167
0168 void IOVProxy::loadGroups() {
0169
0170
0171
0172 resetIOVCache();
0173
0174
0175 m_session->iovSchema().iovTable().getGroups(m_data->tagInfo.name,
0176 m_data->snapshotTime,
0177 cond::time::sinceGroupSize(m_data->tagInfo.timeType),
0178 m_data->sinceGroups);
0179 m_data->cacheInitialized = true;
0180 }
0181
0182 IOVArray IOVProxy::selectAll() {
0183 boost::posix_time::ptime no_time;
0184 return selectAll(no_time);
0185 }
0186
0187 IOVArray IOVProxy::selectAll(const boost::posix_time::ptime& snapshottime) {
0188 if (!m_data.get())
0189 throwException("No tag has been loaded.", "IOVProxy::selectAll");
0190 checkTransaction("IOVProxy::selectAll");
0191 IOVArray ret;
0192 ret.m_tagInfo = m_data->tagInfo;
0193 m_session->iovSchema().iovTable().select(
0194 m_data->tagInfo.name, cond::time::MIN_VAL, cond::time::MAX_VAL, snapshottime, *ret.m_array);
0195 return ret;
0196 }
0197
0198 IOVArray IOVProxy::selectRange(const cond::Time_t& begin, const cond::Time_t& end) {
0199 boost::posix_time::ptime no_time;
0200 return selectRange(begin, end, no_time);
0201 }
0202
0203 IOVArray IOVProxy::selectRange(const cond::Time_t& begin,
0204 const cond::Time_t& end,
0205 const boost::posix_time::ptime& snapshotTime) {
0206 if (!m_data.get())
0207 throwException("No tag has been loaded.", "IOVProxy::selectRange");
0208
0209 checkTransaction("IOVProxy::selectRange");
0210
0211 IOVArray ret;
0212 ret.m_tagInfo = m_data->tagInfo;
0213 m_session->iovSchema().iovTable().getRange(m_data->tagInfo.name, begin, end, snapshotTime, *ret.m_array);
0214 return ret;
0215 }
0216
0217 bool IOVProxy::selectRange(const cond::Time_t& begin, const cond::Time_t& end, IOVContainer& destination) {
0218 if (!m_data.get())
0219 throwException("No tag has been loaded.", "IOVProxy::selectRange");
0220
0221 checkTransaction("IOVProxy::selectRange");
0222
0223 boost::posix_time::ptime no_time;
0224 size_t prevSize = destination.size();
0225 m_session->iovSchema().iovTable().getRange(m_data->tagInfo.name, begin, end, no_time, destination);
0226 size_t niov = destination.size() - prevSize;
0227 return niov > 0;
0228 }
0229
0230 void IOVProxy::resetIOVCache() {
0231 if (m_data.get()) {
0232 m_data->groupLowerIov = cond::time::MAX_VAL;
0233 m_data->groupHigherIov = cond::time::MIN_VAL;
0234 m_data->sinceGroups.clear();
0235 m_data->iovSequence.clear();
0236 m_data->numberOfQueries = 0;
0237 }
0238 }
0239
0240 void IOVProxy::reset() {
0241 if (m_data.get()) {
0242 m_data->tagInfo.clear();
0243 }
0244 resetIOVCache();
0245 }
0246
0247 cond::Tag_t IOVProxy::tagInfo() const { return m_data.get() ? m_data->tagInfo : cond::Tag_t(); }
0248
0249 void setTillToLastIov(cond::Iov_t& target, cond::Time_t endOfValidity) {
0250 if (endOfValidity < cond::time::MAX_VAL) {
0251 if (target.since >= endOfValidity) {
0252 target.clear();
0253 } else {
0254 target.till = endOfValidity;
0255 }
0256 } else {
0257 target.till = cond::time::MAX_VAL;
0258 }
0259 }
0260
0261 cond::TagInfo_t IOVProxy::iovSequenceInfo() const {
0262 if (!m_data.get())
0263 throwException("No tag has been loaded.", "IOVProxy::iovSequenceInfo");
0264 checkTransaction("IOVProxy::iovSequenceInfo");
0265 cond::TagInfo_t ret;
0266 m_session->iovSchema().iovTable().getSize(m_data->tagInfo.name, m_data->snapshotTime, ret.size);
0267 cond::Iov_t last;
0268 bool ok = m_session->iovSchema().iovTable().getLastIov(
0269 m_data->tagInfo.name, m_data->snapshotTime, ret.lastInterval.since, ret.lastInterval.payloadId);
0270 if (ok) {
0271 setTillToLastIov(ret.lastInterval, m_data->tagInfo.endOfValidity);
0272 }
0273 return ret;
0274 }
0275
0276 std::tuple<std::string, boost::posix_time::ptime, boost::posix_time::ptime> IOVProxy::getMetadata() const {
0277 if (!m_data.get())
0278 throwException("No tag has been loaded.", "IOVProxy::getMetadata");
0279 checkTransaction("IOVProxy::getMetadata");
0280 std::tuple<std::string, boost::posix_time::ptime, boost::posix_time::ptime> ret;
0281 if (!m_session->iovSchema().tagTable().getMetadata(
0282 m_data->tagInfo.name, std::get<0>(ret), std::get<1>(ret), std::get<2>(ret))) {
0283 throwException("Metadata for tag \"" + m_data->tagInfo.name + "\" have not been found in the database.",
0284 "IOVProxy::getMetadata");
0285 }
0286 return ret;
0287 }
0288
0289 void IOVProxy::checkTransaction(const std::string& ctx) const {
0290 if (!m_session.get())
0291 throwException("The session is not active.", ctx);
0292 if (!m_session->isTransactionActive(false))
0293 throwException("The transaction is not active.", ctx);
0294 }
0295
0296 void IOVProxy::fetchSequence(cond::Time_t lowerGroup, cond::Time_t higherGroup) {
0297 bool firstTime = m_data->iovSequence.empty();
0298 m_data->iovSequence.clear();
0299 m_session->iovSchema().iovTable().select(
0300 m_data->tagInfo.name, lowerGroup, higherGroup, m_data->snapshotTime, m_data->iovSequence);
0301
0302 if (m_data->iovSequence.empty()) {
0303 m_data->groupLowerIov = cond::time::MAX_VAL;
0304 m_data->groupHigherIov = cond::time::MIN_VAL;
0305 } else {
0306 if (lowerGroup > cond::time::MIN_VAL) {
0307 m_data->groupLowerIov = std::get<0>(m_data->iovSequence.front());
0308 } else {
0309 m_data->groupLowerIov = cond::time::MIN_VAL;
0310 }
0311 m_data->groupHigherIov = std::get<0>(m_data->iovSequence.back());
0312 if (higherGroup < cond::time::MAX_VAL) {
0313 m_data->groupHigherIov = cond::time::tillTimeFromNextSince(higherGroup, m_data->tagInfo.timeType);
0314 } else {
0315 m_data->groupHigherIov = cond::time::MAX_VAL;
0316 }
0317 }
0318 if (not firstTime) {
0319 edm::LogSystem("NewIOV") << "Fetched new IOV for '" << m_data->tagInfo.name << "' request interval [ "
0320 << lowerGroup << " , " << higherGroup << " ] new range [ " << m_data->groupLowerIov
0321 << " , " << m_data->groupHigherIov << " ] #entries " << m_data->iovSequence.size();
0322 }
0323
0324 m_data->numberOfQueries++;
0325 }
0326
0327 cond::Iov_t IOVProxy::getInterval(cond::Time_t time) {
0328 if (!m_data.get())
0329 throwException("No tag has been loaded.", "IOVProxy::getInterval");
0330 checkTransaction("IOVProxy::getInterval");
0331 if (!m_data->cacheInitialized)
0332 loadGroups();
0333 cond::Iov_t retVal;
0334
0335
0336 if (m_data->groupLowerIov == cond::time::MAX_VAL ||
0337 time < m_data->groupLowerIov || time >= m_data->groupHigherIov) {
0338
0339
0340
0341 auto iGLow = search(time, m_data->sinceGroups);
0342 if (iGLow == m_data->sinceGroups.end()) {
0343
0344 return retVal;
0345 }
0346 auto iGHigh = iGLow;
0347 cond::Time_t lowG = *iGLow;
0348 iGHigh++;
0349 cond::Time_t highG = cond::time::MAX_VAL;
0350 if (iGHigh != m_data->sinceGroups.end())
0351 highG = *iGHigh;
0352
0353
0354 fetchSequence(lowG, highG);
0355 }
0356
0357
0358 auto iIov = search(time, m_data->iovSequence);
0359 if (iIov == m_data->iovSequence.end()) {
0360 return retVal;
0361 }
0362
0363 retVal.since = std::get<0>(*iIov);
0364 auto next = iIov;
0365 next++;
0366
0367
0368 retVal.till = m_data->tagInfo.endOfValidity;
0369
0370 cond::Time_t tillVal;
0371 if (next != m_data->iovSequence.end()) {
0372 tillVal = cond::time::tillTimeFromNextSince(std::get<0>(*next), m_data->tagInfo.timeType);
0373 } else {
0374 tillVal = m_data->groupHigherIov;
0375 }
0376 if (tillVal < retVal.till)
0377 retVal.till = tillVal;
0378
0379 retVal.payloadId = std::get<1>(*iIov);
0380 return retVal;
0381 }
0382
0383 cond::Iov_t IOVProxy::getLast() {
0384 checkTransaction("IOVProxy::getLast");
0385 cond::Iov_t ret;
0386 bool ok = m_session->iovSchema().iovTable().getLastIov(
0387 m_data->tagInfo.name, m_data->snapshotTime, ret.since, ret.payloadId);
0388 if (ok) {
0389 setTillToLastIov(ret, m_data->tagInfo.endOfValidity);
0390 }
0391 return ret;
0392 }
0393
0394 int IOVProxy::loadedSize() const { return m_data.get() ? m_data->iovSequence.size() : 0; }
0395
0396 int IOVProxy::sequenceSize() const {
0397 checkTransaction("IOVProxy::sequenceSize");
0398 size_t ret = 0;
0399 m_session->iovSchema().iovTable().getSize(m_data->tagInfo.name, m_data->snapshotTime, ret);
0400
0401 return ret;
0402 }
0403
0404 size_t IOVProxy::numberOfQueries() const { return m_data.get() ? m_data->numberOfQueries : 0; }
0405
0406 std::pair<cond::Time_t, cond::Time_t> IOVProxy::loadedGroup() const {
0407 return m_data.get() ? std::make_pair(m_data->groupLowerIov, m_data->groupHigherIov)
0408 : std::make_pair(cond::time::MAX_VAL, cond::time::MIN_VAL);
0409 }
0410
0411 const std::shared_ptr<SessionImpl>& IOVProxy::session() const { return m_session; }
0412
0413 }
0414
0415 }