00001 #include "DataFormats/Provenance/interface/IndexIntoFile.h"
00002 #include "FWCore/Utilities/interface/Algorithms.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004
00005 #include <algorithm>
00006 #include <ostream>
00007 #include <iomanip>
00008
00009 namespace edm {
00010
00011 int const IndexIntoFile::invalidIndex;
00012 RunNumber_t const IndexIntoFile::invalidRun;
00013 LuminosityBlockNumber_t const IndexIntoFile::invalidLumi;
00014 EventNumber_t const IndexIntoFile::invalidEvent;
00015 IndexIntoFile::EntryNumber_t const IndexIntoFile::invalidEntry;
00016
00017 IndexIntoFile::IndexIntoFile() : transients_(),
00018 processHistoryIDs_(),
00019 runOrLumiEntries_() {
00020 }
00021
00022 IndexIntoFile::~IndexIntoFile() {
00023 }
00024
00025 ProcessHistoryID const& IndexIntoFile::processHistoryID(int i) const {
00026 return processHistoryIDs_.at(i);
00027 }
00028
00029 std::vector<ProcessHistoryID> const& IndexIntoFile::processHistoryIDs() const {
00030 return processHistoryIDs_;
00031 }
00032
00033 void
00034 IndexIntoFile::addEntry(ProcessHistoryID const& processHistoryID,
00035 RunNumber_t run,
00036 LuminosityBlockNumber_t lumi,
00037 EventNumber_t event,
00038 EntryNumber_t entry) {
00039 int index = 0;
00040
00041
00042
00043 if (previousAddedIndex() != invalidIndex &&
00044 processHistoryID == processHistoryIDs_[previousAddedIndex()]) {
00045 index = previousAddedIndex();
00046 }
00047
00048
00049
00050 else {
00051 index = 0;
00052 while (index < static_cast<int>(processHistoryIDs_.size()) &&
00053 processHistoryIDs_[index] != processHistoryID) {
00054 ++index;
00055 }
00056 if (index == static_cast<int>(processHistoryIDs_.size())) {
00057 processHistoryIDs_.push_back(processHistoryID);
00058 }
00059 }
00060 previousAddedIndex() = index;
00061
00062 assert((currentRun() == run && currentIndex() == index) || currentRun() == invalidRun);
00063 if (lumi == invalidLumi) {
00064 if (currentLumi() != invalidLumi) {
00065 throw Exception(errors::LogicError)
00066 << "In IndexIntoFile::addEntry. Entries were added in illegal order.\n"
00067 << "This means the IndexIntoFile product in the output file will be corrupted.\n"
00068 << "The output file will be unusable for most purposes.\n"
00069 << "If this occurs after an unrelated exception was thrown in\n"
00070 << "endLuminosityBlock or endRun then ignore this exception and fix\n"
00071 << "the primary exception. This is an expected side effect.\n"
00072 << "Otherwise please report this to the core framework developers\n";
00073 }
00074 currentIndex() = invalidIndex;
00075 currentRun() = invalidRun;
00076 currentLumi() = invalidLumi;
00077 std::pair<IndexRunKey, EntryNumber_t> firstRunEntry(IndexRunKey(index, run), entry);
00078 runToFirstEntry().insert(firstRunEntry);
00079 RunOrLumiEntry runEntry(runToFirstEntry()[IndexRunKey(index, run)], invalidEntry, entry, index, run, lumi, invalidEntry, invalidEntry);
00080 runOrLumiEntries_.push_back(runEntry);
00081 }
00082 else {
00083 assert(currentLumi() == lumi || currentLumi() == invalidLumi);
00084 if (currentRun() == invalidRun) {
00085 currentRun() = run;
00086 currentIndex() = index;
00087 }
00088 if (event == invalidEvent) {
00089 currentLumi() = invalidLumi;
00090 std::pair<IndexRunLumiKey, EntryNumber_t> firstLumiEntry(IndexRunLumiKey(index, run, lumi), entry);
00091 lumiToFirstEntry().insert(firstLumiEntry);
00092 RunOrLumiEntry lumiEntry(invalidEntry, lumiToFirstEntry()[IndexRunLumiKey(index, run, lumi)],
00093 entry, index, run, lumi, beginEvents(), endEvents());
00094 runOrLumiEntries_.push_back(lumiEntry);
00095 beginEvents() = invalidEntry;
00096 endEvents() = invalidEntry;
00097 }
00098 else {
00099 setNumberOfEvents(numberOfEvents() + 1);
00100 if (beginEvents() == invalidEntry) {
00101 currentLumi() = lumi;
00102 beginEvents() = entry;
00103 endEvents() = beginEvents() + 1;
00104 }
00105 else {
00106 assert(currentLumi() == lumi);
00107 assert(entry == endEvents());
00108 ++endEvents();
00109 }
00110 }
00111 }
00112 }
00113
00114 void IndexIntoFile::fillRunOrLumiIndexes() const {
00115 if (runOrLumiEntries_.empty() || !runOrLumiIndexes().empty()) {
00116 return;
00117 }
00118 runOrLumiIndexes().reserve(runOrLumiEntries_.size());
00119
00120 int index = 0;
00121 for (std::vector<RunOrLumiEntry>::const_iterator iter = runOrLumiEntries_.begin(),
00122 iEnd = runOrLumiEntries_.end();
00123 iter != iEnd;
00124 ++iter, ++index) {
00125 runOrLumiIndexes().push_back(RunOrLumiIndexes(iter->processHistoryIDIndex(),
00126 iter->run(),
00127 iter->lumi(),
00128 index));
00129 }
00130 stable_sort_all(runOrLumiIndexes());
00131
00132 long long beginEventNumbers = 0;
00133
00134 std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
00135 std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
00136 std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
00137 while (true) {
00138 while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
00139 ++beginOfLumi;
00140 }
00141 if (beginOfLumi == iEnd) break;
00142
00143 endOfLumi = beginOfLumi + 1;
00144 while (endOfLumi != iEnd &&
00145 beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
00146 beginOfLumi->run() == endOfLumi->run() &&
00147 beginOfLumi->lumi() == endOfLumi->lumi()) {
00148 ++endOfLumi;
00149 }
00150 int nEvents = 0;
00151 for (std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi;
00152 iter != endOfLumi;
00153 ++iter) {
00154 if (runOrLumiEntries_[iter->indexToGetEntry()].beginEvents() != invalidEntry) {
00155 nEvents += runOrLumiEntries_[iter->indexToGetEntry()].endEvents() -
00156 runOrLumiEntries_[iter->indexToGetEntry()].beginEvents();
00157 }
00158 }
00159 for (std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi;
00160 iter != endOfLumi;
00161 ++iter) {
00162 iter->setBeginEventNumbers(beginEventNumbers);
00163 iter->setEndEventNumbers(beginEventNumbers + nEvents);
00164 }
00165 beginEventNumbers += nEvents;
00166 beginOfLumi = endOfLumi;
00167 }
00168 assert(runOrLumiIndexes().size() == runOrLumiEntries_.size());
00169 }
00170
00171 void
00172 IndexIntoFile::fillEventNumbers() const {
00173 fillEventNumbersOrEntries(true, false);
00174 }
00175
00176 void
00177 IndexIntoFile::fillEventEntries() const {
00178 fillEventNumbersOrEntries(false, true);
00179 }
00180
00181 void
00182 IndexIntoFile::fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const {
00183 if (numberOfEvents() == 0) {
00184 return;
00185 }
00186
00187 if (needEventNumbers && !eventNumbers().empty()) {
00188 needEventNumbers = false;
00189 }
00190
00191 if (needEventEntries && !eventEntries().empty()) {
00192 needEventEntries = false;
00193 }
00194
00195 if (needEventNumbers && !eventEntries().empty()) {
00196 assert(numberOfEvents() == eventEntries().size());
00197 eventNumbers().reserve(eventEntries().size());
00198 for (std::vector<EventNumber_t>::size_type entry = 0U; entry < numberOfEvents(); ++entry) {
00199 eventNumbers().push_back(eventEntries()[entry].event());
00200 }
00201 return;
00202 }
00203
00204 if (!needEventNumbers && !needEventEntries) {
00205 return;
00206 }
00207
00208 fillUnsortedEventNumbers();
00209
00210 if (needEventNumbers) {
00211 eventNumbers().resize(numberOfEvents(), IndexIntoFile::invalidEvent);
00212 }
00213 if (needEventEntries) {
00214 eventEntries().resize(numberOfEvents());
00215 }
00216
00217 long long offset = 0;
00218 long long previousBeginEventNumbers = -1LL;
00219
00220 for (SortedRunOrLumiItr runOrLumi = beginRunOrLumi(), runOrLumiEnd = endRunOrLumi();
00221 runOrLumi != runOrLumiEnd; ++runOrLumi) {
00222
00223 if (runOrLumi.isRun()) continue;
00224
00225 long long beginEventNumbers = 0;
00226 long long endEventNumbers = 0;
00227 EntryNumber_t beginEventEntry = -1LL;
00228 EntryNumber_t endEventEntry = -1LL;
00229 runOrLumi.getRange(beginEventNumbers, endEventNumbers, beginEventEntry, endEventEntry);
00230
00231
00232
00233 if (beginEventNumbers != previousBeginEventNumbers) offset = 0;
00234
00235 for (EntryNumber_t entry = beginEventEntry; entry != endEventEntry; ++entry) {
00236 if (needEventNumbers) {
00237 eventNumbers().at((entry - beginEventEntry) + offset + beginEventNumbers) = unsortedEventNumbers().at(entry);
00238 }
00239 if (needEventEntries) {
00240 eventEntries().at((entry - beginEventEntry) + offset + beginEventNumbers) =
00241 EventEntry(unsortedEventNumbers().at(entry), entry);
00242 }
00243 }
00244
00245 previousBeginEventNumbers = beginEventNumbers;
00246 offset += endEventEntry - beginEventEntry;
00247 }
00248 if (needEventNumbers) {
00249 sortEvents();
00250 assert(numberOfEvents() == eventNumbers().size());
00251 }
00252 if (needEventEntries) {
00253 sortEventEntries();
00254 assert(numberOfEvents() == eventEntries().size());
00255 }
00256 }
00257
00258 void
00259 IndexIntoFile::fillUnsortedEventNumbers() const {
00260 if (numberOfEvents() == 0 || !unsortedEventNumbers().empty()) {
00261 return;
00262 }
00263 unsortedEventNumbers().reserve(numberOfEvents());
00264
00265
00266
00267
00268
00269
00270
00271 for (std::vector<EventNumber_t>::size_type entry = 0U; entry < numberOfEvents(); ++entry) {
00272 unsortedEventNumbers().push_back(getEventNumberOfEntry(entry));
00273 }
00274 }
00275
00276
00277
00278
00279 void
00280 IndexIntoFile::inputFileClosed() const {
00281 std::vector<EventEntry>().swap(eventEntries());
00282 std::vector<RunOrLumiIndexes>().swap(runOrLumiIndexes());
00283 std::vector<EventNumber_t>().swap(unsortedEventNumbers());
00284 resetEventFinder();
00285 }
00286
00287 void
00288 IndexIntoFile::doneFileInitialization() const {
00289 std::vector<EventNumber_t>().swap(unsortedEventNumbers());
00290 }
00291
00292 void
00293 IndexIntoFile::fixIndexes(std::vector<ProcessHistoryID> & processHistoryIDs) {
00294
00295 std::map<int, int> oldToNewIndex;
00296 for (std::vector<ProcessHistoryID>::const_iterator iter = processHistoryIDs_.begin(),
00297 iEnd = processHistoryIDs_.end();
00298 iter != iEnd;
00299 ++iter) {
00300 std::vector<ProcessHistoryID>::const_iterator iterExisting =
00301 std::find(processHistoryIDs.begin(), processHistoryIDs.end(), *iter);
00302 if (iterExisting == processHistoryIDs.end()) {
00303 oldToNewIndex[iter - processHistoryIDs_.begin()] = processHistoryIDs.size();
00304 processHistoryIDs.push_back(*iter);
00305 }
00306 else {
00307 oldToNewIndex[iter - processHistoryIDs_.begin()] = iterExisting - processHistoryIDs.begin();
00308 }
00309 }
00310 processHistoryIDs_ = processHistoryIDs;
00311
00312 for (std::vector<RunOrLumiEntry>::iterator iter = runOrLumiEntries_.begin(),
00313 iEnd = runOrLumiEntries_.end();
00314 iter != iEnd;
00315 ++iter) {
00316 iter->setProcessHistoryIDIndex(oldToNewIndex[iter->processHistoryIDIndex()]);
00317 }
00318 }
00319
00320 void IndexIntoFile::sortVector_Run_Or_Lumi_Entries() {
00321 for (std::vector<RunOrLumiEntry>::iterator iter = runOrLumiEntries_.begin(),
00322 iEnd = runOrLumiEntries_.end();
00323 iter != iEnd;
00324 ++iter) {
00325 std::map<IndexRunKey, EntryNumber_t>::const_iterator firstRunEntry =
00326 runToFirstEntry().find(IndexRunKey(iter->processHistoryIDIndex(), iter->run()));
00327 if (firstRunEntry == runToFirstEntry().end()) {
00328 throw Exception(errors::LogicError)
00329 << "In IndexIntoFile::sortVector_Run_Or_Lumi_Entries. A run entry is missing.\n"
00330 << "This means the IndexIntoFile product in the output file will be corrupted.\n"
00331 << "The output file will be unusable for most purposes.\n"
00332 << "If this occurs after an unrelated exception was thrown in\n"
00333 << "endLuminosityBlock or endRun then ignore this exception and fix\n"
00334 << "the primary exception. This is an expected side effect.\n"
00335 << "Otherwise please report this to the core framework developers\n";
00336 }
00337 iter->setOrderPHIDRun(firstRunEntry->second);
00338 }
00339 stable_sort_all(runOrLumiEntries_);
00340 }
00341
00342 void IndexIntoFile::sortEvents() const {
00343 fillRunOrLumiIndexes();
00344 std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
00345 std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
00346 std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
00347 while (true) {
00348 while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
00349 ++beginOfLumi;
00350 }
00351 if (beginOfLumi == iEnd) break;
00352
00353 endOfLumi = beginOfLumi + 1;
00354 while (endOfLumi != iEnd &&
00355 beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
00356 beginOfLumi->run() == endOfLumi->run() &&
00357 beginOfLumi->lumi() == endOfLumi->lumi()) {
00358 ++endOfLumi;
00359 }
00360 assert(beginOfLumi->endEventNumbers() >= 0);
00361 assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventNumbers().size()));
00362 std::sort(eventNumbers().begin() + beginOfLumi->beginEventNumbers(),
00363 eventNumbers().begin() + beginOfLumi->endEventNumbers());
00364 beginOfLumi = endOfLumi;
00365 }
00366 }
00367
00368 void IndexIntoFile::sortEventEntries() const {
00369 fillRunOrLumiIndexes();
00370 std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
00371 std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
00372 std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
00373 while (true) {
00374 while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
00375 ++beginOfLumi;
00376 }
00377 if (beginOfLumi == iEnd) break;
00378
00379 endOfLumi = beginOfLumi + 1;
00380 while (endOfLumi != iEnd &&
00381 beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
00382 beginOfLumi->run() == endOfLumi->run() &&
00383 beginOfLumi->lumi() == endOfLumi->lumi()) {
00384 ++endOfLumi;
00385 }
00386 assert(beginOfLumi->endEventNumbers() >= 0);
00387 assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventEntries().size()));
00388 std::sort(eventEntries().begin() + beginOfLumi->beginEventNumbers(),
00389 eventEntries().begin() + beginOfLumi->endEventNumbers());
00390 beginOfLumi = endOfLumi;
00391 }
00392 }
00393
00394 IndexIntoFile::IndexIntoFileItr IndexIntoFile::begin(SortOrder sortOrder) const {
00395 if (empty()) {
00396 return end(sortOrder);
00397 }
00398 IndexIntoFileItr iter(this,
00399 sortOrder,
00400 kRun,
00401 0,
00402 invalidIndex,
00403 invalidIndex,
00404 0,
00405 0);
00406 iter.initializeRun();
00407 return iter;
00408 }
00409
00410 IndexIntoFile::IndexIntoFileItr IndexIntoFile::end(SortOrder sortOrder) const {
00411 return IndexIntoFileItr(this,
00412 sortOrder,
00413 kEnd,
00414 invalidIndex,
00415 invalidIndex,
00416 invalidIndex,
00417 0,
00418 0);
00419 }
00420
00421 bool IndexIntoFile::iterationWillBeInEntryOrder(SortOrder sortOrder) const {
00422 EntryNumber_t maxEntry = invalidEntry;
00423 for(IndexIntoFileItr it = begin(sortOrder), itEnd = end(sortOrder); it != itEnd; ++it) {
00424 if(it.getEntryType() == kEvent) {
00425 if(it.entry() < maxEntry) {
00426 return false;
00427 }
00428 maxEntry = it.entry();
00429 }
00430 }
00431 return true;
00432 }
00433
00434 bool IndexIntoFile::empty() const {
00435 return runOrLumiEntries().empty();
00436 }
00437
00438 IndexIntoFile::IndexIntoFileItr
00439 IndexIntoFile::findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00440 fillRunOrLumiIndexes();
00441
00442 bool lumiMissing = (lumi == 0 && event != 0);
00443
00444 std::vector<RunOrLumiIndexes>::const_iterator it;
00445 std::vector<RunOrLumiIndexes>::const_iterator iEnd = runOrLumiIndexes().end();
00446 std::vector<RunOrLumiIndexes>::const_iterator phEnd;
00447
00448
00449 for (std::vector<RunOrLumiIndexes>::const_iterator phBegin = runOrLumiIndexes().begin();
00450 phBegin != iEnd;
00451 phBegin = phEnd) {
00452
00453 RunOrLumiIndexes el(phBegin->processHistoryIDIndex(), run, lumi, 0);
00454 phEnd = std::upper_bound(phBegin, iEnd, el, Compare_Index());
00455
00456 std::vector<RunOrLumiIndexes>::const_iterator iRun = std::lower_bound(phBegin, phEnd, el, Compare_Index_Run());
00457
00458 if (iRun == phEnd || iRun->run() != run) continue;
00459
00460 if (lumi == invalidLumi && event == invalidEvent) {
00461 IndexIntoFileItr indexItr(this,
00462 numericalOrder,
00463 kRun,
00464 iRun - runOrLumiIndexes().begin(),
00465 invalidIndex,
00466 invalidIndex,
00467 0,
00468 0);
00469 indexItr.initializeRun();
00470 return indexItr;
00471 }
00472
00473 std::vector<RunOrLumiIndexes>::const_iterator iRunEnd = std::upper_bound(iRun, phEnd, el, Compare_Index_Run());
00474 if (!lumiMissing) {
00475
00476 std::vector<RunOrLumiIndexes>::const_iterator iLumi = std::lower_bound(iRun, iRunEnd, el);
00477 if (iLumi == iRunEnd || iLumi->lumi() != lumi) continue;
00478
00479 if (event == invalidEvent) {
00480 IndexIntoFileItr indexItr(this,
00481 numericalOrder,
00482 kRun,
00483 iRun - runOrLumiIndexes().begin(),
00484 iLumi - runOrLumiIndexes().begin(),
00485 invalidIndex,
00486 0,
00487 0);
00488 indexItr.initializeLumi();
00489 return indexItr;
00490 }
00491
00492 long long beginEventNumbers = iLumi->beginEventNumbers();
00493 long long endEventNumbers = iLumi->endEventNumbers();
00494 if (beginEventNumbers >= endEventNumbers) continue;
00495
00496
00497 long long indexToEvent = 0;
00498 if (!eventEntries().empty()) {
00499 std::vector<EventEntry>::const_iterator eventIter = std::lower_bound(eventEntries().begin() + beginEventNumbers,
00500 eventEntries().begin() + endEventNumbers,
00501 EventEntry(event, invalidEntry));
00502 if (eventIter == (eventEntries().begin() + endEventNumbers) ||
00503 eventIter->event() != event) continue;
00504
00505 indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
00506 } else {
00507 fillEventNumbers();
00508 std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(eventNumbers().begin() + beginEventNumbers,
00509 eventNumbers().begin() + endEventNumbers,
00510 event);
00511 if (eventIter == (eventNumbers().begin() + endEventNumbers) ||
00512 *eventIter != event) continue;
00513
00514 indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
00515 }
00516 return IndexIntoFileItr(this,
00517 numericalOrder,
00518 kRun,
00519 iRun - runOrLumiIndexes().begin(),
00520 iLumi - runOrLumiIndexes().begin(),
00521 iLumi - runOrLumiIndexes().begin(),
00522 indexToEvent,
00523 endEventNumbers - beginEventNumbers);
00524 }
00525 if (lumiMissing) {
00526
00527 std::vector<RunOrLumiIndexes>::const_iterator iLumi = iRun;
00528 while (iLumi != iRunEnd && iLumi->lumi() == invalidLumi) {
00529 ++iLumi;
00530 }
00531 if (iLumi == iRunEnd) continue;
00532
00533 std::vector<RunOrLumiIndexes>::const_iterator lumiEnd;
00534 for ( ;
00535 iLumi != iRunEnd;
00536 iLumi = lumiEnd) {
00537
00538 RunOrLumiIndexes elWithLumi(phBegin->processHistoryIDIndex(), run, iLumi->lumi(), 0);
00539 lumiEnd = std::upper_bound(iLumi, iRunEnd, elWithLumi);
00540
00541 long long beginEventNumbers = iLumi->beginEventNumbers();
00542 long long endEventNumbers = iLumi->endEventNumbers();
00543 if (beginEventNumbers >= endEventNumbers) continue;
00544
00545 long long indexToEvent = 0;
00546 if (!eventEntries().empty()) {
00547 std::vector<EventEntry>::const_iterator eventIter = std::lower_bound(eventEntries().begin() + beginEventNumbers,
00548 eventEntries().begin() + endEventNumbers,
00549 EventEntry(event, invalidEntry));
00550 if (eventIter == (eventEntries().begin() + endEventNumbers) ||
00551 eventIter->event() != event) continue;
00552 indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
00553 } else {
00554 fillEventNumbers();
00555 std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(eventNumbers().begin() + beginEventNumbers,
00556 eventNumbers().begin() + endEventNumbers,
00557 event);
00558 if (eventIter == (eventNumbers().begin() + endEventNumbers) ||
00559 *eventIter != event) continue;
00560 indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
00561 }
00562 return IndexIntoFileItr(this,
00563 numericalOrder,
00564 kRun,
00565 iRun - runOrLumiIndexes().begin(),
00566 iLumi - runOrLumiIndexes().begin(),
00567 iLumi - runOrLumiIndexes().begin(),
00568 indexToEvent,
00569 endEventNumbers - beginEventNumbers);
00570 }
00571 }
00572 }
00573
00574 return IndexIntoFileItr(this,
00575 numericalOrder,
00576 kEnd,
00577 invalidIndex,
00578 invalidIndex,
00579 invalidIndex,
00580 0,
00581 0);
00582
00583 }
00584
00585 IndexIntoFile::IndexIntoFileItr
00586 IndexIntoFile::findPosition(SortOrder sortOrder, RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00587 if (sortOrder == IndexIntoFile::numericalOrder) {
00588 return findPosition(run, lumi, event);
00589 }
00590 IndexIntoFileItr itr = begin(sortOrder);
00591 IndexIntoFileItr itrEnd = end(sortOrder);
00592
00593 while (itr != itrEnd) {
00594 if (itr.run() != run) {
00595 itr.advanceToNextRun();
00596 }
00597 else {
00598 if (lumi == invalidLumi && event == invalidEvent) {
00599 return itr;
00600 }
00601 else if (lumi != invalidLumi && itr.peekAheadAtLumi() != lumi) {
00602 if (!itr.skipLumiInRun()) {
00603 itr.advanceToNextRun();
00604 }
00605 }
00606 else {
00607 if (event == invalidEvent) {
00608 return itr;
00609 }
00610 else {
00611 EventNumber_t eventNumber = getEventNumberOfEntry(itr.peekAheadAtEventEntry());
00612 if (eventNumber == event) {
00613 return itr;
00614 }
00615 else {
00616 if (!itr.skipToNextEventInLumi()) {
00617 if (!itr.skipLumiInRun()) {
00618 itr.advanceToNextRun();
00619 }
00620 }
00621 }
00622 }
00623 }
00624 }
00625 }
00626 return itrEnd;
00627 }
00628
00629 IndexIntoFile::IndexIntoFileItr
00630 IndexIntoFile::findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00631 assert(event != invalidEvent);
00632 IndexIntoFileItr iter = findPosition(run, lumi, event);
00633 iter.advanceToEvent();
00634 return iter;
00635 }
00636
00637 IndexIntoFile::IndexIntoFileItr
00638 IndexIntoFile::findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const {
00639 assert(lumi != invalidLumi);
00640 IndexIntoFileItr iter = findPosition(run, lumi, 0U);
00641 iter.advanceToLumi();
00642 return iter;
00643 }
00644
00645 IndexIntoFile::IndexIntoFileItr
00646 IndexIntoFile::findRunPosition(RunNumber_t run) const {
00647 return findPosition(run, 0U, 0U);
00648 }
00649
00650 bool
00651 IndexIntoFile::containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00652 return event ? containsEvent(run, lumi, event) : (lumi ? containsLumi(run, lumi) : containsRun(run));
00653 }
00654
00655 bool
00656 IndexIntoFile::containsEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const {
00657 return findEventPosition(run, lumi, event).getEntryType() != kEnd;
00658 }
00659
00660 bool
00661 IndexIntoFile::containsLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) const {
00662 return findLumiPosition(run, lumi).getEntryType() != kEnd;
00663 }
00664
00665 bool
00666 IndexIntoFile::containsRun(RunNumber_t run) const {
00667 return findRunPosition(run).getEntryType() != kEnd;
00668 }
00669
00670 IndexIntoFile::SortedRunOrLumiItr IndexIntoFile::beginRunOrLumi() const {
00671 return SortedRunOrLumiItr(this, 0);
00672 }
00673
00674 IndexIntoFile::SortedRunOrLumiItr IndexIntoFile::endRunOrLumi() const {
00675 return SortedRunOrLumiItr(this, runOrLumiEntries().size());
00676 }
00677
00678 void IndexIntoFile::set_intersection(IndexIntoFile const& indexIntoFile,
00679 std::set<IndexRunLumiEventKey> & intersection) const {
00680
00681 if (empty() || indexIntoFile.empty()) return;
00682 fillRunOrLumiIndexes();
00683 indexIntoFile.fillRunOrLumiIndexes();
00684 RunOrLumiIndexes const& back1 = runOrLumiIndexes().back();
00685 RunOrLumiIndexes const& back2 = indexIntoFile.runOrLumiIndexes().back();
00686
00687
00688 if (back2 < runOrLumiIndexes().front()) return;
00689 if (back1 < indexIntoFile.runOrLumiIndexes().front()) return;
00690
00691 SortedRunOrLumiItr iter1 = beginRunOrLumi();
00692 SortedRunOrLumiItr iEnd1 = endRunOrLumi();
00693
00694 SortedRunOrLumiItr iter2 = indexIntoFile.beginRunOrLumi();
00695 SortedRunOrLumiItr iEnd2 = indexIntoFile.endRunOrLumi();
00696
00697
00698 while (iter1 != iEnd1 && iter1.isRun()) ++iter1;
00699 if (iter1 == iEnd1) return;
00700 if (back2 < iter1.runOrLumiIndexes()) return;
00701
00702 while (iter2 != iEnd2 && iter2.isRun()) ++iter2;
00703 if (iter2 == iEnd2) return;
00704 if (back1 < iter2.runOrLumiIndexes()) return;
00705
00706 RunOrLumiIndexes const* previousIndexes = 0;
00707
00708
00709 while (iter1 != iEnd1 && iter2 != iEnd2) {
00710
00711 RunOrLumiIndexes const& indexes1 = iter1.runOrLumiIndexes();
00712 RunOrLumiIndexes const& indexes2 = iter2.runOrLumiIndexes();
00713 if (indexes1 < indexes2) {
00714 ++iter1;
00715 }
00716 else if (indexes2 < indexes1) {
00717 ++iter2;
00718 }
00719 else {
00720
00721
00722 if (indexes1.isRun() ||
00723 (previousIndexes && !(*previousIndexes < indexes1))) {
00724 ++iter1;
00725 ++iter2;
00726 }
00727 else {
00728 previousIndexes = &indexes1;
00729
00730
00731
00732 long long beginEventNumbers1 = indexes1.beginEventNumbers();
00733 long long endEventNumbers1 = indexes1.endEventNumbers();
00734
00735 long long beginEventNumbers2 = indexes2.beginEventNumbers();
00736 long long endEventNumbers2 = indexes2.endEventNumbers();
00737
00738
00739 if ((beginEventNumbers1 >= endEventNumbers1) ||
00740 (beginEventNumbers2 >= endEventNumbers2)) {
00741 ++iter1;
00742 ++iter2;
00743 continue;
00744 }
00745
00746 if (!eventEntries().empty() && !indexIntoFile.eventEntries().empty()) {
00747 std::vector<EventEntry> matchingEvents;
00748 std::insert_iterator<std::vector<EventEntry> > insertIter(matchingEvents, matchingEvents.begin());
00749 std::set_intersection(eventEntries().begin() + beginEventNumbers1,
00750 eventEntries().begin() + endEventNumbers1,
00751 indexIntoFile.eventEntries().begin() + beginEventNumbers2,
00752 indexIntoFile.eventEntries().begin() + endEventNumbers2,
00753 insertIter);
00754 for (std::vector<EventEntry>::const_iterator iEvent = matchingEvents.begin(),
00755 iEnd = matchingEvents.end();
00756 iEvent != iEnd; ++iEvent) {
00757 intersection.insert(IndexRunLumiEventKey(indexes1.processHistoryIDIndex(),
00758 indexes1.run(),
00759 indexes1.lumi(),
00760 iEvent->event()));
00761 }
00762 } else {
00763 fillEventNumbers();
00764 indexIntoFile.fillEventNumbers();
00765 std::vector<EventNumber_t> matchingEvents;
00766 std::insert_iterator<std::vector<EventNumber_t> > insertIter(matchingEvents, matchingEvents.begin());
00767 std::set_intersection(eventNumbers().begin() + beginEventNumbers1,
00768 eventNumbers().begin() + endEventNumbers1,
00769 indexIntoFile.eventNumbers().begin() + beginEventNumbers2,
00770 indexIntoFile.eventNumbers().begin() + endEventNumbers2,
00771 insertIter);
00772 for (std::vector<EventNumber_t>::const_iterator iEvent = matchingEvents.begin(),
00773 iEnd = matchingEvents.end();
00774 iEvent != iEnd; ++iEvent) {
00775 intersection.insert(IndexRunLumiEventKey(indexes1.processHistoryIDIndex(),
00776 indexes1.run(),
00777 indexes1.lumi(),
00778 *iEvent));
00779 }
00780 }
00781 }
00782 }
00783 }
00784 }
00785
00786 bool IndexIntoFile::containsDuplicateEvents() const {
00787
00788 RunOrLumiIndexes const* previousIndexes = 0;
00789
00790 for (SortedRunOrLumiItr iter = beginRunOrLumi(),
00791 iEnd = endRunOrLumi();
00792 iter != iEnd; ++iter) {
00793
00794 RunOrLumiIndexes const& indexes = iter.runOrLumiIndexes();
00795
00796
00797 if (indexes.isRun() ||
00798 (previousIndexes && !(*previousIndexes < indexes))) {
00799 continue;
00800 }
00801 previousIndexes = &indexes;
00802
00803 long long beginEventNumbers = indexes.beginEventNumbers();
00804 long long endEventNumbers = indexes.endEventNumbers();
00805
00806
00807 if (beginEventNumbers + 1 >= endEventNumbers) continue;
00808
00809 if (!eventEntries().empty()) {
00810 std::vector<EventEntry>::iterator last = eventEntries().begin() + endEventNumbers;
00811 if (std::adjacent_find(eventEntries().begin() + beginEventNumbers, last) != last) {
00812 return true;
00813 }
00814 } else {
00815 fillEventNumbers();
00816 std::vector<EventNumber_t>::iterator last = eventNumbers().begin() + endEventNumbers;
00817 if (std::adjacent_find(eventNumbers().begin() + beginEventNumbers, last) != last) {
00818 return true;
00819 }
00820 }
00821 }
00822 return false;
00823 }
00824
00825 IndexIntoFile::RunOrLumiEntry::RunOrLumiEntry() :
00826 orderPHIDRun_(invalidEntry),
00827 orderPHIDRunLumi_(invalidEntry),
00828 entry_(invalidEntry),
00829 processHistoryIDIndex_(invalidIndex),
00830 run_(invalidRun),
00831 lumi_(invalidLumi),
00832 beginEvents_(invalidEntry),
00833 endEvents_(invalidEntry) {
00834 }
00835
00836 IndexIntoFile::RunOrLumiEntry::RunOrLumiEntry(EntryNumber_t orderPHIDRun,
00837 EntryNumber_t orderPHIDRunLumi,
00838 EntryNumber_t entry,
00839 int processHistoryIDIndex,
00840 RunNumber_t run,
00841 LuminosityBlockNumber_t lumi,
00842 EntryNumber_t beginEvents,
00843 EntryNumber_t endEvents) :
00844 orderPHIDRun_(orderPHIDRun),
00845 orderPHIDRunLumi_(orderPHIDRunLumi),
00846 entry_(entry),
00847 processHistoryIDIndex_(processHistoryIDIndex),
00848 run_(run),
00849 lumi_(lumi),
00850 beginEvents_(beginEvents),
00851 endEvents_(endEvents) {
00852 }
00853
00854 IndexIntoFile::RunOrLumiIndexes::RunOrLumiIndexes(int processHistoryIDIndex,
00855 RunNumber_t run,
00856 LuminosityBlockNumber_t lumi,
00857 int indexToGetEntry) :
00858 processHistoryIDIndex_(processHistoryIDIndex),
00859 run_(run),
00860 lumi_(lumi),
00861 indexToGetEntry_(indexToGetEntry),
00862 beginEventNumbers_(-1),
00863 endEventNumbers_(-1)
00864 {
00865 }
00866
00867 IndexIntoFile::SortedRunOrLumiItr::SortedRunOrLumiItr(IndexIntoFile const* indexIntoFile, unsigned runOrLumi) :
00868 indexIntoFile_(indexIntoFile), runOrLumi_(runOrLumi) {
00869 assert(runOrLumi_ <= indexIntoFile_->runOrLumiEntries().size());
00870 indexIntoFile_->fillRunOrLumiIndexes();
00871 }
00872
00873 bool IndexIntoFile::SortedRunOrLumiItr::operator==(SortedRunOrLumiItr const& right) const {
00874 return indexIntoFile_ == right.indexIntoFile() &&
00875 runOrLumi_ == right.runOrLumi();
00876 }
00877
00878 bool IndexIntoFile::SortedRunOrLumiItr::operator!=(SortedRunOrLumiItr const& right) const {
00879 return indexIntoFile_ != right.indexIntoFile() ||
00880 runOrLumi_ != right.runOrLumi();
00881 }
00882
00883 IndexIntoFile::SortedRunOrLumiItr & IndexIntoFile::SortedRunOrLumiItr::operator++() {
00884 if (runOrLumi_ != indexIntoFile_->runOrLumiEntries().size()) {
00885 ++runOrLumi_;
00886 }
00887 return *this;
00888 }
00889
00890 bool IndexIntoFile::SortedRunOrLumiItr::isRun() {
00891 return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).lumi() == invalidLumi;
00892 }
00893
00894 void IndexIntoFile::SortedRunOrLumiItr::getRange(long long & beginEventNumbers,
00895 long long & endEventNumbers,
00896 EntryNumber_t & beginEventEntry,
00897 EntryNumber_t & endEventEntry) {
00898 beginEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).beginEventNumbers();
00899 endEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).endEventNumbers();
00900
00901 int indexToGetEntry = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).indexToGetEntry();
00902 beginEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).beginEvents();
00903 endEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).endEvents();
00904 }
00905
00906 IndexIntoFile::RunOrLumiIndexes const&
00907 IndexIntoFile::SortedRunOrLumiItr::runOrLumiIndexes() const {
00908 return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_);
00909 }
00910
00911 IndexIntoFile::IndexIntoFileItrImpl::IndexIntoFileItrImpl(IndexIntoFile const* indexIntoFile,
00912 EntryType entryType,
00913 int indexToRun,
00914 int indexToLumi,
00915 int indexToEventRange,
00916 long long indexToEvent,
00917 long long nEvents) :
00918 indexIntoFile_(indexIntoFile),
00919 size_(static_cast<int>(indexIntoFile_->runOrLumiEntries_.size())),
00920 type_(entryType),
00921 indexToRun_(indexToRun),
00922 indexToLumi_(indexToLumi),
00923 indexToEventRange_(indexToEventRange),
00924 indexToEvent_(indexToEvent),
00925 nEvents_(nEvents) {
00926 }
00927
00928 IndexIntoFile::IndexIntoFileItrImpl::~IndexIntoFileItrImpl() {}
00929
00930 void IndexIntoFile::IndexIntoFileItrImpl::next() {
00931
00932 if (type_ == kEvent) {
00933 if ((indexToEvent_ + 1) < nEvents_) {
00934 ++indexToEvent_;
00935 }
00936 else {
00937 bool found = nextEventRange();
00938
00939 if (!found) {
00940 type_ = getRunOrLumiEntryType(indexToLumi_ + 1);
00941
00942 if (type_ == kLumi) {
00943 ++indexToLumi_;
00944 initializeLumi();
00945 }
00946 else if (type_ == kRun) {
00947 indexToRun_ = indexToLumi_ + 1;
00948 initializeRun();
00949 }
00950 else {
00951 setInvalid();
00952 }
00953 }
00954 }
00955 }
00956 else if (type_ == kLumi) {
00957
00958 if (indexToLumi_ + 1 == size_) {
00959 if (indexToEvent_ < nEvents_) {
00960 type_ = kEvent;
00961 }
00962 else {
00963 setInvalid();
00964 }
00965 }
00966 else {
00967
00968 EntryType nextType = getRunOrLumiEntryType(indexToLumi_ + 1);
00969
00970 if (nextType == kLumi && isSameLumi(indexToLumi_, indexToLumi_ + 1)) {
00971 ++indexToLumi_;
00972 }
00973 else if (indexToEvent_ < nEvents_) {
00974 type_ = kEvent;
00975 }
00976 else if (nextType == kRun) {
00977 type_ = kRun;
00978 indexToRun_ = indexToLumi_ + 1;
00979 initializeRun();
00980 }
00981 else {
00982 ++indexToLumi_;
00983 initializeLumi();
00984 }
00985 }
00986 }
00987 else if (type_ == kRun) {
00988 EntryType nextType = getRunOrLumiEntryType(indexToRun_ + 1);
00989 bool sameRun = isSameRun(indexToRun_, indexToRun_ + 1);
00990 if (nextType == kRun && sameRun) {
00991 ++indexToRun_;
00992 }
00993 else if (nextType == kRun && !sameRun) {
00994 ++indexToRun_;
00995 initializeRun();
00996 }
00997 else if (nextType == kLumi) {
00998 type_ = kLumi;
00999 }
01000 else {
01001 setInvalid();
01002 }
01003 }
01004 }
01005
01006 void IndexIntoFile::IndexIntoFileItrImpl::skipEventForward(int & phIndexOfSkippedEvent,
01007 RunNumber_t & runOfSkippedEvent,
01008 LuminosityBlockNumber_t & lumiOfSkippedEvent,
01009 EntryNumber_t & skippedEventEntry) {
01010 if (indexToEvent_ < nEvents_) {
01011 phIndexOfSkippedEvent = processHistoryIDIndex();
01012 runOfSkippedEvent = run();
01013 lumiOfSkippedEvent = peekAheadAtLumi();
01014 skippedEventEntry = peekAheadAtEventEntry();
01015
01016 if ((indexToEvent_ + 1) < nEvents_) {
01017 ++indexToEvent_;
01018 return;
01019 }
01020 else if (nextEventRange()) {
01021 return;
01022 }
01023 else if (type_ == kRun || type_ == kLumi) {
01024 if (skipLumiInRun()) {
01025 return;
01026 }
01027 }
01028 else if (type_ == kEvent) {
01029 next();
01030 return;
01031 }
01032 advanceToNextRun();
01033 return;
01034 }
01035
01036 if (type_ == kRun) {
01037 while (skipLumiInRun()) {
01038 if (indexToEvent_ < nEvents_) {
01039 skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
01040 return;
01041 }
01042 }
01043 }
01044
01045 while (indexToEvent_ >= nEvents_ && type_ != kEnd) {
01046 while (skipLumiInRun()) {
01047 if (indexToEvent_ < nEvents_) {
01048 skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
01049 return;
01050 }
01051 }
01052 advanceToNextRun();
01053 }
01054 if (type_ == kEnd) {
01055 phIndexOfSkippedEvent = invalidIndex;
01056 runOfSkippedEvent = invalidRun;
01057 lumiOfSkippedEvent = invalidLumi;
01058 skippedEventEntry = invalidEntry;
01059 return;
01060 }
01061 skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
01062 return;
01063 }
01064
01065 void IndexIntoFile::IndexIntoFileItrImpl::skipEventBackward(int& phIndexOfEvent,
01066 RunNumber_t& runOfEvent,
01067 LuminosityBlockNumber_t& lumiOfEvent,
01068 EntryNumber_t& eventEntry) {
01069
01070 if (indexToEvent_ > 0) {
01071 --indexToEvent_;
01072 }
01073 else if (!previousEventRange()) {
01074
01075
01076 if (!previousLumiWithEvents()) {
01077
01078
01079
01080 if (!indexIntoFile_->empty()) {
01081
01082 type_ = kRun;
01083 indexToRun_ = 0;
01084 initializeRun();
01085 }
01086 phIndexOfEvent = invalidIndex;
01087 runOfEvent = invalidRun;
01088 lumiOfEvent = invalidLumi;
01089 eventEntry = invalidEntry;
01090 return;
01091 }
01092 }
01093
01094
01095
01096
01097 phIndexOfEvent = processHistoryIDIndex();
01098 runOfEvent = run();
01099 lumiOfEvent = peekAheadAtLumi();
01100 eventEntry = peekAheadAtEventEntry();
01101 }
01102
01103 bool IndexIntoFile::IndexIntoFileItrImpl::previousLumiWithEvents() {
01104
01105 int newLumi = indexToLumi();
01106 if (newLumi == invalidIndex) {
01107 newLumi = indexToRun() == invalidIndex ? size() - 1 : indexToRun();
01108 }
01109 else {
01110 while (getRunOrLumiEntryType(newLumi - 1) == kLumi &&
01111 isSameLumi(newLumi, newLumi - 1)) {
01112 --newLumi;
01113 }
01114 --newLumi;
01115 }
01116 if (newLumi <= 0) return false;
01117
01118
01119 for ( ; newLumi > 0; --newLumi) {
01120 if (getRunOrLumiEntryType(newLumi) == kRun) {
01121 continue;
01122 }
01123 if (setToLastEventInRange(newLumi)) {
01124 break;
01125 }
01126 }
01127 if (newLumi == 0) return false;
01128
01129
01130 while (getRunOrLumiEntryType(newLumi - 1) == kLumi &&
01131 isSameLumi(newLumi, newLumi - 1)) {
01132 --newLumi;
01133 }
01134 setIndexToLumi(newLumi);
01135
01136 if (type() != kEnd &&
01137 isSameRun(newLumi, indexToRun())) {
01138 if (type() == kEvent) type_ = kLumi;
01139 return true;
01140 }
01141 int newRun = newLumi;
01142 while (newRun > 0 && getRunOrLumiEntryType(newRun - 1) == kLumi) {
01143 --newRun;
01144 }
01145 --newRun;
01146 assert(getRunOrLumiEntryType(newRun) == kRun);
01147 while (getRunOrLumiEntryType(newRun - 1) == kRun &&
01148 isSameRun(newRun - 1, newLumi)) {
01149 --newRun;
01150 }
01151 indexToRun_ = newRun;
01152 type_ = kRun;
01153 return true;
01154 }
01155
01156 void IndexIntoFile::IndexIntoFileItrImpl::advanceToNextRun() {
01157 if (type_ == kEnd) return;
01158 for (int i = 1; indexToRun_ + i < size_; ++i) {
01159 if (getRunOrLumiEntryType(indexToRun_ + i) == kRun) {
01160 if (!isSameRun(indexToRun_, indexToRun_ + i)) {
01161 type_ = kRun;
01162 indexToRun_ += i;
01163 initializeRun();
01164 return;
01165 }
01166 }
01167 }
01168 setInvalid();
01169 }
01170
01171 void IndexIntoFile::IndexIntoFileItrImpl::advanceToNextLumiOrRun() {
01172 if (type_ == kEnd) return;
01173 assert(indexToRun_ != invalidIndex);
01174
01175
01176
01177
01178 int startSearch = indexToRun_;
01179 for (int i = 1; startSearch + i < size_; ++i) {
01180 if (getRunOrLumiEntryType(startSearch + i) == kRun &&
01181 isSameRun(indexToRun_, startSearch + i)) {
01182 indexToRun_ = startSearch + i;
01183 }
01184 else {
01185 break;
01186 }
01187 }
01188
01189 if (type_ == kRun && indexToLumi_ != invalidIndex) {
01190 type_ = kLumi;
01191 return;
01192 }
01193
01194 startSearch = indexToLumi_;
01195 if (startSearch == invalidIndex) startSearch = indexToRun_;
01196 for (int i = 1; startSearch + i < size_; ++i) {
01197 if (getRunOrLumiEntryType(startSearch + i) == kRun) {
01198 if (!isSameRun(indexToRun_, startSearch + i)) {
01199 type_ = kRun;
01200 indexToRun_ = startSearch + i;
01201 initializeRun();
01202 return;
01203 }
01204 }
01205 else if (indexToLumi_ != invalidIndex) {
01206 if (!isSameLumi(indexToLumi_, startSearch + i)) {
01207 type_ = kLumi;
01208 indexToLumi_ = startSearch + i;
01209 initializeLumi();
01210 return;
01211 }
01212 }
01213 }
01214 setInvalid();
01215 }
01216
01217 bool IndexIntoFile::IndexIntoFileItrImpl::skipToNextEventInLumi() {
01218 if (indexToEvent_ >= nEvents_) return false;
01219 if ((indexToEvent_ + 1) < nEvents_) {
01220 ++indexToEvent_;
01221 return true;
01222 }
01223 return nextEventRange();
01224 }
01225
01226 void IndexIntoFile::IndexIntoFileItrImpl::initializeRun() {
01227
01228 indexToLumi_ = invalidIndex;
01229 indexToEventRange_ = invalidIndex;
01230 indexToEvent_ = 0;
01231 nEvents_ = 0;
01232
01233 for (int i = 1; (i + indexToRun_) < size_; ++i) {
01234 EntryType entryType = getRunOrLumiEntryType(indexToRun_ + i);
01235 bool sameRun = isSameRun(indexToRun_, indexToRun_ + i);
01236
01237 if (entryType == kRun) {
01238 if (sameRun) {
01239 continue;
01240 }
01241 else {
01242 break;
01243 }
01244 }
01245 else {
01246 indexToLumi_ = indexToRun_ + i;
01247 initializeLumi();
01248 return;
01249 }
01250 }
01251 }
01252
01253 bool IndexIntoFile::IndexIntoFileItrImpl::operator==(IndexIntoFileItrImpl const& right) const {
01254 return (indexIntoFile_ == right.indexIntoFile_ &&
01255 size_ == right.size_ &&
01256 type_ == right.type_ &&
01257 indexToRun_ == right.indexToRun_ &&
01258 indexToLumi_ == right.indexToLumi_ &&
01259 indexToEventRange_ == right.indexToEventRange_ &&
01260 indexToEvent_ == right.indexToEvent_ &&
01261 nEvents_ == right.nEvents_);
01262 }
01263
01264 void
01265 IndexIntoFile::IndexIntoFileItrImpl::copyPosition(IndexIntoFileItrImpl const& position) {
01266 type_ = position.type_;
01267 indexToRun_ = position.indexToRun_;
01268 indexToLumi_ = position.indexToLumi_;
01269 indexToEventRange_ = position.indexToEventRange_;
01270 indexToEvent_ = position.indexToEvent_;
01271 nEvents_ = position.nEvents_;
01272 }
01273
01274 void IndexIntoFile::IndexIntoFileItrImpl::setInvalid() {
01275 type_ = kEnd;
01276 indexToRun_ = invalidIndex;
01277 indexToLumi_ = invalidIndex;
01278 indexToEventRange_ = invalidIndex;
01279 indexToEvent_ = 0;
01280 nEvents_ = 0;
01281 }
01282
01283 IndexIntoFile::IndexIntoFileItrNoSort::IndexIntoFileItrNoSort(IndexIntoFile const* indexIntoFile,
01284 EntryType entryType,
01285 int indexToRun,
01286 int indexToLumi,
01287 int indexToEventRange,
01288 long long indexToEvent,
01289 long long nEvents) :
01290 IndexIntoFileItrImpl(indexIntoFile,
01291 entryType,
01292 indexToRun,
01293 indexToLumi,
01294 indexToEventRange,
01295 indexToEvent,
01296 nEvents)
01297 {
01298 }
01299
01300 IndexIntoFile::IndexIntoFileItrImpl*
01301 IndexIntoFile::IndexIntoFileItrNoSort::clone() const {
01302 return new IndexIntoFileItrNoSort(*this);
01303 }
01304
01305 int
01306 IndexIntoFile::IndexIntoFileItrNoSort::processHistoryIDIndex() const {
01307 if (type() == kEnd) return invalidIndex;
01308 return indexIntoFile()->runOrLumiEntries()[indexToRun()].processHistoryIDIndex();
01309 }
01310
01311 RunNumber_t IndexIntoFile::IndexIntoFileItrNoSort::run() const {
01312 if (type() == kEnd) return invalidRun;
01313 return indexIntoFile()->runOrLumiEntries()[indexToRun()].run();
01314 }
01315
01316 LuminosityBlockNumber_t IndexIntoFile::IndexIntoFileItrNoSort::lumi() const {
01317 if (type() == kEnd || type() == kRun) return invalidLumi;
01318 return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
01319 }
01320
01321 IndexIntoFile::EntryNumber_t IndexIntoFile::IndexIntoFileItrNoSort::entry() const {
01322 if (type() == kEnd) return invalidEntry;
01323 if (type() == kRun) return indexIntoFile()->runOrLumiEntries()[indexToRun()].entry();
01324 if (type() == kLumi) return indexIntoFile()->runOrLumiEntries()[indexToLumi()].entry();
01325 return
01326 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() +
01327 indexToEvent();
01328 }
01329
01330 LuminosityBlockNumber_t IndexIntoFile::IndexIntoFileItrNoSort::peekAheadAtLumi() const {
01331 if (indexToLumi() == invalidIndex) return invalidLumi;
01332 return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
01333 }
01334
01335 IndexIntoFile::EntryNumber_t IndexIntoFile::IndexIntoFileItrNoSort::peekAheadAtEventEntry() const {
01336 if (indexToLumi() == invalidIndex) return invalidEntry;
01337 if (indexToEvent() >= nEvents()) return invalidEntry;
01338 return
01339 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() +
01340 indexToEvent();
01341 }
01342
01343 void IndexIntoFile::IndexIntoFileItrNoSort::initializeLumi_() {
01344 assert(indexToLumi() != invalidIndex);
01345
01346 setIndexToEventRange(invalidIndex);
01347 setIndexToEvent(0);
01348 setNEvents(0);
01349
01350 for (int i = 0; indexToLumi() + i < size(); ++i) {
01351 if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].isRun()) {
01352 break;
01353 }
01354 else if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].lumi() ==
01355 indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
01356 if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].beginEvents() == invalidEntry) {
01357 continue;
01358 }
01359 setIndexToEventRange(indexToLumi() + i);
01360 setIndexToEvent(0);
01361 setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
01362 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
01363 break;
01364 }
01365 else {
01366 break;
01367 }
01368 }
01369 }
01370
01371 bool IndexIntoFile::IndexIntoFileItrNoSort::nextEventRange() {
01372 if (indexToEventRange() == invalidIndex) return false;
01373
01374
01375 for(int i = 1; indexToEventRange() + i < size(); ++i) {
01376 if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i ].isRun()) {
01377 return false;
01378 }
01379 else if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].lumi() ==
01380 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].lumi()) {
01381 if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].beginEvents() == invalidEntry) {
01382 continue;
01383 }
01384 setIndexToEventRange(indexToEventRange() + i);
01385 setIndexToEvent(0);
01386 setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
01387 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
01388 return true;
01389 }
01390 return false;
01391 }
01392 return false;
01393 }
01394
01395 bool IndexIntoFile::IndexIntoFileItrNoSort::previousEventRange() {
01396 if (indexToEventRange() == invalidIndex) return false;
01397 assert(indexToEventRange() < size());
01398
01399
01400 for(int i = 1; indexToEventRange() - i > 0; ++i) {
01401 int newRange = indexToEventRange() - i;
01402 if (indexIntoFile()->runOrLumiEntries()[newRange].isRun()) {
01403 return false;
01404 }
01405 else if (isSameLumi(newRange, indexToEventRange())) {
01406 if (indexIntoFile()->runOrLumiEntries()[newRange].beginEvents() == invalidEntry) {
01407 continue;
01408 }
01409 setIndexToEventRange(newRange);
01410 setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
01411 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
01412 setIndexToEvent(nEvents() - 1);
01413 return true;
01414 }
01415 return false;
01416 }
01417 return false;
01418 }
01419
01420 bool IndexIntoFile::IndexIntoFileItrNoSort::setToLastEventInRange(int index) {
01421 if (indexIntoFile()->runOrLumiEntries()[index].beginEvents() == invalidEntry) {
01422 return false;
01423 }
01424 setIndexToEventRange(index);
01425 setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
01426 indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
01427 assert(nEvents() > 0);
01428 setIndexToEvent(nEvents() - 1);
01429 return true;
01430 }
01431
01432 bool IndexIntoFile::IndexIntoFileItrNoSort::skipLumiInRun() {
01433 if (indexToLumi() == invalidIndex) return false;
01434 for(int i = 1; indexToLumi() + i < size(); ++i) {
01435 int newLumi = indexToLumi() + i;
01436 if (indexIntoFile()->runOrLumiEntries()[newLumi].isRun()) {
01437 return false;
01438 }
01439 else if (indexIntoFile()->runOrLumiEntries()[newLumi].lumi() ==
01440 indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
01441 continue;
01442 }
01443 setIndexToLumi(newLumi);
01444 initializeLumi();
01445 return true;
01446 }
01447 return false;
01448 }
01449
01450 IndexIntoFile::EntryType IndexIntoFile::IndexIntoFileItrNoSort::getRunOrLumiEntryType(int index) const {
01451 if (index < 0 || index >= size()) {
01452 return kEnd;
01453 }
01454 else if (indexIntoFile()->runOrLumiEntries()[index].isRun()) {
01455 return kRun;
01456 }
01457 return kLumi;
01458 }
01459
01460 bool IndexIntoFile::IndexIntoFileItrNoSort::isSameLumi(int index1, int index2) const {
01461 if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
01462 return false;
01463 }
01464 return indexIntoFile()->runOrLumiEntries()[index1].lumi() ==
01465 indexIntoFile()->runOrLumiEntries()[index2].lumi();
01466 }
01467
01468 bool IndexIntoFile::IndexIntoFileItrNoSort::isSameRun(int index1, int index2) const {
01469 if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
01470 return false;
01471 }
01472 return indexIntoFile()->runOrLumiEntries()[index1].run() ==
01473 indexIntoFile()->runOrLumiEntries()[index2].run() &&
01474 indexIntoFile()->runOrLumiEntries()[index1].processHistoryIDIndex() ==
01475 indexIntoFile()->runOrLumiEntries()[index2].processHistoryIDIndex();
01476 }
01477
01478 IndexIntoFile::IndexIntoFileItrSorted::IndexIntoFileItrSorted(IndexIntoFile const* indexIntoFile,
01479 EntryType entryType,
01480 int indexToRun,
01481 int indexToLumi,
01482 int indexToEventRange,
01483 long long indexToEvent,
01484 long long nEvents) :
01485 IndexIntoFileItrImpl(indexIntoFile,
01486 entryType,
01487 indexToRun,
01488 indexToLumi,
01489 indexToEventRange,
01490 indexToEvent,
01491 nEvents) {
01492 indexIntoFile->fillRunOrLumiIndexes();
01493 }
01494
01495 IndexIntoFile::IndexIntoFileItrImpl* IndexIntoFile::IndexIntoFileItrSorted::clone() const {
01496 return new IndexIntoFileItrSorted(*this);
01497 }
01498
01499 int IndexIntoFile::IndexIntoFileItrSorted::processHistoryIDIndex() const {
01500 if (type() == kEnd) return invalidIndex;
01501 return indexIntoFile()->runOrLumiIndexes()[indexToRun()].processHistoryIDIndex();
01502 }
01503
01504 RunNumber_t IndexIntoFile::IndexIntoFileItrSorted::run() const {
01505 if (type() == kEnd) return invalidRun;
01506 return indexIntoFile()->runOrLumiIndexes()[indexToRun()].run();
01507 }
01508
01509 LuminosityBlockNumber_t IndexIntoFile::IndexIntoFileItrSorted::lumi() const {
01510 if (type() == kEnd || type() == kRun) return invalidLumi;
01511 return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
01512 }
01513
01514 IndexIntoFile::EntryNumber_t IndexIntoFile::IndexIntoFileItrSorted::entry() const {
01515 if (type() == kEnd) return invalidEntry;
01516 if (type() == kRun) {
01517 int i = indexIntoFile()->runOrLumiIndexes()[indexToRun()].indexToGetEntry();
01518 return indexIntoFile()->runOrLumiEntries()[i].entry();
01519 }
01520 if (type() == kLumi) {
01521 int i = indexIntoFile()->runOrLumiIndexes()[indexToLumi()].indexToGetEntry();
01522 return indexIntoFile()->runOrLumiEntries()[i].entry();
01523 }
01524 long long eventNumberIndex =
01525 indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() +
01526 indexToEvent();
01527 indexIntoFile()->fillEventEntries();
01528 return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
01529 }
01530
01531 LuminosityBlockNumber_t IndexIntoFile::IndexIntoFileItrSorted::peekAheadAtLumi() const {
01532 if (indexToLumi() == invalidIndex) return invalidLumi;
01533 return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
01534 }
01535
01536 IndexIntoFile::EntryNumber_t IndexIntoFile::IndexIntoFileItrSorted::peekAheadAtEventEntry() const {
01537 if (indexToLumi() == invalidIndex) return invalidEntry;
01538 if (indexToEvent() >= nEvents()) return invalidEntry;
01539 long long eventNumberIndex =
01540 indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() +
01541 indexToEvent();
01542 indexIntoFile()->fillEventEntries();
01543 return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
01544 }
01545
01546 void IndexIntoFile::IndexIntoFileItrSorted::initializeLumi_() {
01547 assert(indexToLumi() != invalidIndex);
01548 setIndexToEventRange(indexToLumi());
01549 setIndexToEvent(0);
01550 setNEvents(
01551 indexIntoFile()->runOrLumiIndexes()[indexToLumi()].endEventNumbers() -
01552 indexIntoFile()->runOrLumiIndexes()[indexToLumi()].beginEventNumbers());
01553 if (nEvents() == 0){
01554 setIndexToEventRange(invalidIndex);
01555 }
01556 }
01557
01558 bool IndexIntoFile::IndexIntoFileItrSorted::nextEventRange() {
01559 return false;
01560 }
01561
01562 bool IndexIntoFile::IndexIntoFileItrSorted::previousEventRange() {
01563 return false;
01564 }
01565
01566 bool IndexIntoFile::IndexIntoFileItrSorted::setToLastEventInRange(int index) {
01567 long long nEventsInRange =
01568 indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
01569 indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers();
01570 if (nEventsInRange == 0) {
01571 return false;
01572 }
01573 while (index > 0 &&
01574 !indexIntoFile()->runOrLumiIndexes()[index - 1].isRun() &&
01575 isSameLumi(index, index - 1)) {
01576 --index;
01577 }
01578 assert(nEventsInRange ==
01579 indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
01580 indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers());
01581
01582 setIndexToEventRange(index);
01583 setNEvents(nEventsInRange);
01584 assert(nEvents() > 0);
01585 setIndexToEvent(nEventsInRange - 1);
01586 return true;
01587 }
01588
01589 bool IndexIntoFile::IndexIntoFileItrSorted::skipLumiInRun() {
01590 if (indexToLumi() == invalidIndex) return false;
01591 for(int i = 1; indexToLumi() + i < size(); ++i) {
01592 int newLumi = indexToLumi() + i;
01593 if (indexIntoFile()->runOrLumiIndexes()[newLumi].isRun()) {
01594 return false;
01595 }
01596 else if (indexIntoFile()->runOrLumiIndexes()[newLumi].lumi() ==
01597 indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi()) {
01598 continue;
01599 }
01600 setIndexToLumi(newLumi);
01601 initializeLumi();
01602 return true;
01603 }
01604 return false;
01605 }
01606
01607 IndexIntoFile::EntryType IndexIntoFile::IndexIntoFileItrSorted::getRunOrLumiEntryType(int index) const {
01608 if (index < 0 || index >= size()) {
01609 return kEnd;
01610 }
01611 else if (indexIntoFile()->runOrLumiIndexes()[index].isRun()) {
01612 return kRun;
01613 }
01614 return kLumi;
01615 }
01616
01617 bool IndexIntoFile::IndexIntoFileItrSorted::isSameLumi(int index1, int index2) const {
01618 if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
01619 return false;
01620 }
01621 return indexIntoFile()->runOrLumiIndexes()[index1].lumi() ==
01622 indexIntoFile()->runOrLumiIndexes()[index2].lumi();
01623 }
01624
01625 bool IndexIntoFile::IndexIntoFileItrSorted::isSameRun(int index1, int index2) const {
01626 if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
01627 return false;
01628 }
01629 return indexIntoFile()->runOrLumiIndexes()[index1].run() ==
01630 indexIntoFile()->runOrLumiIndexes()[index2].run() &&
01631 indexIntoFile()->runOrLumiIndexes()[index1].processHistoryIDIndex() ==
01632 indexIntoFile()->runOrLumiIndexes()[index2].processHistoryIDIndex();
01633 }
01634
01635 IndexIntoFile::IndexIntoFileItr::IndexIntoFileItr(IndexIntoFile const* indexIntoFile,
01636 SortOrder sortOrder,
01637 EntryType entryType,
01638 int indexToRun,
01639 int indexToLumi,
01640 int indexToEventRange,
01641 long long indexToEvent,
01642 long long nEvents) :
01643 impl_() {
01644 if (sortOrder == numericalOrder) {
01645 value_ptr<IndexIntoFileItrImpl> temp(new IndexIntoFileItrSorted(indexIntoFile,
01646 entryType,
01647 indexToRun,
01648 indexToLumi,
01649 indexToEventRange,
01650 indexToEvent,
01651 nEvents
01652 ));
01653 swap(temp, impl_);
01654 }
01655 else {
01656 value_ptr<IndexIntoFileItrImpl> temp(new IndexIntoFileItrNoSort(indexIntoFile,
01657 entryType,
01658 indexToRun,
01659 indexToLumi,
01660 indexToEventRange,
01661 indexToEvent,
01662 nEvents));
01663 swap(temp, impl_);
01664 }
01665 }
01666
01667 void IndexIntoFile::IndexIntoFileItr::advanceToEvent() {
01668 for (EntryType entryType = getEntryType();
01669 entryType != kEnd && entryType != kEvent;
01670 entryType = getEntryType()) {
01671 impl_->next();
01672 }
01673 }
01674
01675 void IndexIntoFile::IndexIntoFileItr::advanceToLumi() {
01676 for (EntryType entryType = getEntryType();
01677 entryType != kEnd && entryType != kLumi;
01678 entryType = getEntryType()) {
01679 impl_->next();
01680 }
01681 }
01682
01683 void
01684 IndexIntoFile::IndexIntoFileItr::copyPosition(IndexIntoFileItr const& position) {
01685 impl_->copyPosition(*position.impl_);
01686 }
01687
01688 IndexIntoFile::Transients::Transients() : previousAddedIndex_(invalidIndex),
01689 runToFirstEntry_(),
01690 lumiToFirstEntry_(),
01691 beginEvents_(invalidEntry),
01692 endEvents_(invalidEntry),
01693 currentIndex_(invalidIndex),
01694 currentRun_(invalidRun),
01695 currentLumi_(invalidLumi),
01696 numberOfEvents_(0),
01697 eventFinder_(),
01698 runOrLumiIndexes_(),
01699 eventNumbers_(),
01700 eventEntries_(),
01701 unsortedEventNumbers_() {
01702 }
01703
01704 bool Compare_Index_Run::operator()(IndexIntoFile::RunOrLumiIndexes const& lh, IndexIntoFile::RunOrLumiIndexes const& rh) {
01705 if (lh.processHistoryIDIndex() == rh.processHistoryIDIndex()) {
01706 return lh.run() < rh.run();
01707 }
01708 return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
01709 }
01710
01711 bool Compare_Index::operator()(IndexIntoFile::RunOrLumiIndexes const& lh, IndexIntoFile::RunOrLumiIndexes const& rh) {
01712 return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
01713 }
01714 }