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