CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
IndexIntoFile.cc
Go to the documentation of this file.
5 
6 #include <algorithm>
7 #include <iomanip>
8 #include <ostream>
9 
10 namespace edm {
11 
17 
19  : previousAddedIndex_(invalidIndex),
20  runToOrder_(),
21  lumiToOrder_(),
22  beginEvents_(invalidEntry),
23  endEvents_(invalidEntry),
24  currentIndex_(invalidIndex),
25  currentRun_(invalidRun),
26  currentLumi_(invalidLumi),
27  numberOfEvents_(0),
28  eventFinder_(),
29  runOrLumiIndexes_(),
30  eventNumbers_(),
31  eventEntries_(),
32  unsortedEventNumbers_() {}
33 
35  previousAddedIndex_ = invalidIndex;
36  runToOrder_.clear();
37  lumiToOrder_.clear();
38  beginEvents_ = invalidEntry;
39  endEvents_ = invalidEntry;
40  currentIndex_ = invalidIndex;
41  currentRun_ = invalidRun;
42  currentLumi_ = invalidLumi;
43  numberOfEvents_ = 0;
44  eventFinder_ = nullptr; // propagate_const<T> has no reset() function
45  runOrLumiIndexes_.clear();
46  eventNumbers_.clear();
47  eventEntries_.clear();
48  unsortedEventNumbers_.clear();
49  }
50 
52 
54 
56 
57  std::vector<ProcessHistoryID> const& IndexIntoFile::processHistoryIDs() const { return processHistoryIDs_; }
58 
60  // assign each lumi an order value sequentially when first seen
61  std::pair<IndexRunLumiKey, EntryNumber_t> keyAndOrder(IndexRunLumiKey(index, run, lumi), lumiToOrder().size());
62  lumiToOrder().insert(keyAndOrder); // does nothing if this key already was inserted
63  runOrLumiEntries_.emplace_back(invalidEntry,
64  lumiToOrder()[IndexRunLumiKey(index, run, lumi)],
65  entry,
66  index,
67  run,
68  lumi,
69  beginEvents(),
70  endEvents());
73  }
74 
75  void IndexIntoFile::addEntry(ProcessHistoryID const& processHistoryID,
80  int index = 0;
81  // First see if the ProcessHistoryID is the same as the previous one.
82  // This is just a performance optimization. We expect to usually get
83  // many in a row that are the same.
84  if (previousAddedIndex() != invalidIndex && processHistoryID == processHistoryIDs_[previousAddedIndex()]) {
85  index = previousAddedIndex();
86  } else {
87  // If it was not the same as the previous one then search through the
88  // entire vector. If it is not there, it needs to be added at the
89  // end.
90  index = 0;
91  while (index < static_cast<int>(processHistoryIDs_.size()) && processHistoryIDs_[index] != processHistoryID) {
92  ++index;
93  }
94  if (index == static_cast<int>(processHistoryIDs_.size())) {
95  processHistoryIDs_.push_back(processHistoryID);
96  }
97  }
99 
100  assert((currentRun() == run && currentIndex() == index) || currentRun() == invalidRun);
101  if (lumi == invalidLumi) {
102  if (currentLumi() != invalidLumi) {
104  << "In IndexIntoFile::addEntry. Entries were added in illegal order.\n"
105  << "This means the IndexIntoFile product in the output file will be corrupted.\n"
106  << "The output file will be unusable for most purposes.\n"
107  << "If this occurs after an unrelated exception was thrown in\n"
108  << "endLuminosityBlock or endRun then ignore this exception and fix\n"
109  << "the primary exception. This is an expected side effect.\n"
110  << "Otherwise please report this to the core framework developers\n";
111  }
115  // assign each run an order value when first seen (using entry but any increasing value would work)
116  std::pair<IndexRunKey, EntryNumber_t> keyAndOrder(IndexRunKey(index, run), entry);
117  runToOrder().insert(keyAndOrder); // Does nothing if this key was already inserted
118  runOrLumiEntries_.emplace_back(
119  runToOrder()[IndexRunKey(index, run)], invalidEntry, entry, index, run, lumi, invalidEntry, invalidEntry);
120  } else {
121  if (currentRun() == invalidRun) {
122  currentRun() = run;
123  currentIndex() = index;
124  }
125  if (event == invalidEvent) {
126  if (currentLumi() != lumi and currentLumi() != invalidLumi) {
127  //we have overlapping lumis so must inject a placeholder
128  addLumi(index, run, currentLumi(), invalidEntry);
129  }
131  addLumi(index, run, lumi, entry);
132  } else {
133  if (currentLumi() != lumi and currentLumi() != invalidLumi) {
134  //We have overlapping lumis so need to inject a placeholder
135  addLumi(index, run, currentLumi(), invalidEntry);
136  }
138  if (beginEvents() == invalidEntry) {
139  currentLumi() = lumi;
140  beginEvents() = entry;
141  endEvents() = beginEvents() + 1;
142  } else {
143  assert(currentLumi() == lumi);
144  assert(entry == endEvents());
145  ++endEvents();
146  }
147  }
148  }
149  }
150 
152  if (runOrLumiEntries_.empty() || !runOrLumiIndexes().empty()) {
153  return;
154  }
155  runOrLumiIndexes().reserve(runOrLumiEntries_.size());
156 
157  int index = 0;
158  for (RunOrLumiEntry const& item : runOrLumiEntries_) {
159  runOrLumiIndexes().emplace_back(item.processHistoryIDIndex(), item.run(), item.lumi(), index);
160  ++index;
161  }
163 
164  long long beginEventNumbers = 0;
165 
166  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
167  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
168  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
169  while (true) {
170  while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
171  ++beginOfLumi;
172  }
173  if (beginOfLumi == iEnd)
174  break;
175 
176  endOfLumi = beginOfLumi + 1;
177  while (endOfLumi != iEnd && beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
178  beginOfLumi->run() == endOfLumi->run() && beginOfLumi->lumi() == endOfLumi->lumi()) {
179  ++endOfLumi;
180  }
181  int nEvents = 0;
182  for (std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi; iter != endOfLumi; ++iter) {
183  if (runOrLumiEntries_[iter->indexToGetEntry()].beginEvents() != invalidEntry) {
184  nEvents += runOrLumiEntries_[iter->indexToGetEntry()].endEvents() -
185  runOrLumiEntries_[iter->indexToGetEntry()].beginEvents();
186  }
187  }
188  for (std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi; iter != endOfLumi; ++iter) {
189  iter->setBeginEventNumbers(beginEventNumbers);
190  iter->setEndEventNumbers(beginEventNumbers + nEvents);
191  }
192  beginEventNumbers += nEvents;
193  beginOfLumi = endOfLumi;
194  }
195  assert(runOrLumiIndexes().size() == runOrLumiEntries_.size());
196  }
197 
199 
201 
202  void IndexIntoFile::fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const {
203  if (numberOfEvents() == 0) {
204  return;
205  }
206 
207  if (needEventNumbers && !eventNumbers().empty()) {
208  needEventNumbers = false;
209  }
210 
211  if (needEventEntries && !eventEntries().empty()) {
212  needEventEntries = false;
213  }
214 
215  if (needEventNumbers && !eventEntries().empty()) {
217  eventNumbers().reserve(eventEntries().size());
219  eventNumbers().push_back(eventEntries()[entry].event());
220  }
221  return;
222  }
223 
224  if (!needEventNumbers && !needEventEntries) {
225  return;
226  }
227 
229 
230  if (needEventNumbers) {
232  }
233  if (needEventEntries) {
234  eventEntries().resize(numberOfEvents());
235  }
236 
237  long long offset = 0;
238  long long previousBeginEventNumbers = -1LL;
239 
240  for (SortedRunOrLumiItr runOrLumi = beginRunOrLumi(), runOrLumiEnd = endRunOrLumi(); runOrLumi != runOrLumiEnd;
241  ++runOrLumi) {
242  if (runOrLumi.isRun())
243  continue;
244 
245  long long beginEventNumbers = 0;
246  long long endEventNumbers = 0;
247  EntryNumber_t beginEventEntry = invalidEntry;
248  EntryNumber_t endEventEntry = invalidEntry;
249  runOrLumi.getRange(beginEventNumbers, endEventNumbers, beginEventEntry, endEventEntry);
250 
251  // This is true each time one hits a new lumi section (except if the previous lumi had
252  // no events, in which case the offset is still 0 anyway)
253  if (beginEventNumbers != previousBeginEventNumbers)
254  offset = 0;
255 
256  for (EntryNumber_t entry = beginEventEntry; entry != endEventEntry; ++entry) {
257  if (needEventNumbers) {
258  eventNumbers().at((entry - beginEventEntry) + offset + beginEventNumbers) = unsortedEventNumbers().at(entry);
259  }
260  if (needEventEntries) {
261  eventEntries().at((entry - beginEventEntry) + offset + beginEventNumbers) =
263  }
264  }
265 
266  previousBeginEventNumbers = beginEventNumbers;
267  offset += endEventEntry - beginEventEntry;
268  }
269  if (needEventNumbers) {
270  sortEvents();
272  }
273  if (needEventEntries) {
276  }
277  }
278 
280  if (numberOfEvents() == 0 || !unsortedEventNumbers().empty()) {
281  return;
282  }
284 
285  // The main purpose for the existence of the unsortedEventNumbers
286  // vector is that it can easily be filled by reading through
287  // the EventAuxiliary branch in the same order as the TTree
288  // entries. fillEventNumbersOrEntries can then use this information
289  // instead of using getEventNumberOfEntry directly and reading
290  // the branch in a different order.
293  }
294  }
295 
296  // We are closing the input file, but we need to keep event numbers.
297  // We can delete the other transient collections by using the swap trick.
298 
300  std::vector<EventEntry>().swap(eventEntries());
301  std::vector<RunOrLumiIndexes>().swap(runOrLumiIndexes());
302  std::vector<EventNumber_t>().swap(unsortedEventNumbers());
304  }
305 
306  void IndexIntoFile::doneFileInitialization() { std::vector<EventNumber_t>().swap(unsortedEventNumbers()); }
307 
309  std::vector<ProcessHistoryID> reducedPHIDs;
310 
311  std::map<ProcessHistoryID, int> reducedPHIDToIndex;
312  std::pair<ProcessHistoryID, int> mapEntry(ProcessHistoryID(), 0);
313  std::pair<std::map<ProcessHistoryID, int>::iterator, bool> insertResult;
314 
315  std::vector<int> phidIndexConverter;
316  for (auto const& phid : processHistoryIDs_) {
317  ProcessHistoryID const& reducedPHID = processHistoryRegistry.reducedProcessHistoryID(phid);
318  mapEntry.first = reducedPHID;
319  insertResult = reducedPHIDToIndex.insert(mapEntry);
320 
321  if (insertResult.second) {
322  insertResult.first->second = reducedPHIDs.size();
323  reducedPHIDs.push_back(reducedPHID);
324  }
325  phidIndexConverter.push_back(insertResult.first->second);
326  }
327  processHistoryIDs_.swap(reducedPHIDs);
328 
329  // If the size of the vector of IDs does not change
330  // then their indexes and the ordering of the Runs and
331  // and Lumis does not change, so we are done.
332  if (processHistoryIDs_.size() == reducedPHIDs.size()) {
333  return;
334  }
335 
336  std::map<IndexIntoFile::IndexRunKey, int> runOrderMap;
337  std::pair<std::map<IndexIntoFile::IndexRunKey, int>::iterator, bool> runInsertResult;
338 
339  std::map<IndexIntoFile::IndexRunLumiKey, int> lumiOrderMap;
340  std::pair<std::map<IndexIntoFile::IndexRunLumiKey, int>::iterator, bool> lumiInsertResult;
341 
342  // loop over all the RunOrLumiEntry's
343  for (auto& item : runOrLumiEntries_) {
344  // Convert the process history index so it points into the new vector of reduced IDs
345  item.setProcessHistoryIDIndex(phidIndexConverter.at(item.processHistoryIDIndex()));
346 
347  // Convert the phid-run order
348  IndexIntoFile::IndexRunKey runKey(item.processHistoryIDIndex(), item.run());
349  runInsertResult = runOrderMap.insert(std::pair<IndexIntoFile::IndexRunKey, int>(runKey, 0));
350  if (runInsertResult.second) {
351  runInsertResult.first->second = item.orderPHIDRun();
352  } else {
353  item.setOrderPHIDRun(runInsertResult.first->second);
354  }
355 
356  // Convert the phid-run-lumi order for the lumi entries
357  if (item.lumi() != 0) {
358  IndexIntoFile::IndexRunLumiKey lumiKey(item.processHistoryIDIndex(), item.run(), item.lumi());
359  lumiInsertResult = lumiOrderMap.insert(std::pair<IndexIntoFile::IndexRunLumiKey, int>(lumiKey, 0));
360  if (lumiInsertResult.second) {
361  lumiInsertResult.first->second = item.orderPHIDRunLumi();
362  } else {
363  item.setOrderPHIDRunLumi(lumiInsertResult.first->second);
364  }
365  }
366  }
367  std::stable_sort(runOrLumiEntries_.begin(), runOrLumiEntries_.end());
368  }
369 
370  void IndexIntoFile::fixIndexes(std::vector<ProcessHistoryID>& processHistoryIDs) {
371  std::map<int, int> oldToNewIndex;
372  for (std::vector<ProcessHistoryID>::const_iterator iter = processHistoryIDs_.begin(),
373  iEnd = processHistoryIDs_.end();
374  iter != iEnd;
375  ++iter) {
376  std::vector<ProcessHistoryID>::const_iterator iterExisting =
377  std::find(processHistoryIDs.begin(), processHistoryIDs.end(), *iter);
378  if (iterExisting == processHistoryIDs.end()) {
379  oldToNewIndex[iter - processHistoryIDs_.begin()] = processHistoryIDs.size();
380  processHistoryIDs.push_back(*iter);
381  } else {
382  oldToNewIndex[iter - processHistoryIDs_.begin()] = iterExisting - processHistoryIDs.begin();
383  }
384  }
386 
388  item.setProcessHistoryIDIndex(oldToNewIndex[item.processHistoryIDIndex()]);
389  }
390  }
391 
394  std::map<IndexRunKey, EntryNumber_t>::const_iterator keyAndOrder =
395  runToOrder().find(IndexRunKey(item.processHistoryIDIndex(), item.run()));
396  if (keyAndOrder == runToOrder().end()) {
398  << "In IndexIntoFile::sortVector_Run_Or_Lumi_Entries. A run entry is missing.\n"
399  << "This means the IndexIntoFile product in the output file will be corrupted.\n"
400  << "The output file will be unusable for most purposes.\n"
401  << "If this occurs after an unrelated exception was thrown in\n"
402  << "endLuminosityBlock or endRun then ignore this exception and fix\n"
403  << "the primary exception. This is an expected side effect.\n"
404  << "Otherwise please report this to the core framework developers\n";
405  }
406  item.setOrderPHIDRun(keyAndOrder->second);
407  }
408  stable_sort_all(runOrLumiEntries_);
409  }
410 
413  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
414  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
415  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
416  while (true) {
417  while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
418  ++beginOfLumi;
419  }
420  if (beginOfLumi == iEnd)
421  break;
422 
423  endOfLumi = beginOfLumi + 1;
424  while (endOfLumi != iEnd && beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
425  beginOfLumi->run() == endOfLumi->run() && beginOfLumi->lumi() == endOfLumi->lumi()) {
426  ++endOfLumi;
427  }
428  assert(beginOfLumi->endEventNumbers() >= 0);
429  assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventNumbers().size()));
430  std::sort(eventNumbers().begin() + beginOfLumi->beginEventNumbers(),
431  eventNumbers().begin() + beginOfLumi->endEventNumbers());
432  beginOfLumi = endOfLumi;
433  }
434  }
435 
438  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
439  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
440  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
441  while (true) {
442  while (beginOfLumi != iEnd && beginOfLumi->isRun()) {
443  ++beginOfLumi;
444  }
445  if (beginOfLumi == iEnd)
446  break;
447 
448  endOfLumi = beginOfLumi + 1;
449  while (endOfLumi != iEnd && beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
450  beginOfLumi->run() == endOfLumi->run() && beginOfLumi->lumi() == endOfLumi->lumi()) {
451  ++endOfLumi;
452  }
453  assert(beginOfLumi->endEventNumbers() >= 0);
454  assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventEntries().size()));
455  std::sort(eventEntries().begin() + beginOfLumi->beginEventNumbers(),
456  eventEntries().begin() + beginOfLumi->endEventNumbers());
457  beginOfLumi = endOfLumi;
458  }
459  }
460 
462  if (empty()) {
463  return end(sortOrder);
464  }
465  IndexIntoFileItr iter(this, sortOrder, kRun, 0, invalidIndex, invalidIndex, 0, 0);
466  iter.initializeRun();
467  return iter;
468  }
469 
471  return IndexIntoFileItr(this, sortOrder, kEnd, invalidIndex, invalidIndex, invalidIndex, 0, 0);
472  }
473 
475  EntryNumber_t maxEntry = invalidEntry;
476  for (IndexIntoFileItr it = begin(sortOrder), itEnd = end(sortOrder); it != itEnd; ++it) {
477  if (it.getEntryType() == kEvent) {
478  if (it.entry() < maxEntry) {
479  return false;
480  }
481  maxEntry = it.entry();
482  }
483  }
484  return true;
485  }
486 
487  bool IndexIntoFile::empty() const { return runOrLumiEntries().empty(); }
488 
491  EventNumber_t event) const {
493 
494  bool lumiMissing = (lumi == 0 && event != 0);
495 
496  std::vector<RunOrLumiIndexes>::const_iterator iEnd = runOrLumiIndexes().end();
497  std::vector<RunOrLumiIndexes>::const_iterator phEnd;
498 
499  // Loop over ranges of entries with the same ProcessHistoryID
500  for (std::vector<RunOrLumiIndexes>::const_iterator phBegin = runOrLumiIndexes().begin(); phBegin != iEnd;
501  phBegin = phEnd) {
502  RunOrLumiIndexes el(phBegin->processHistoryIDIndex(), run, lumi, 0);
503  phEnd = std::upper_bound(phBegin, iEnd, el, Compare_Index());
504 
505  std::vector<RunOrLumiIndexes>::const_iterator iRun = std::lower_bound(phBegin, phEnd, el, Compare_Index_Run());
506 
507  if (iRun == phEnd || iRun->run() != run)
508  continue;
509 
510  if (lumi == invalidLumi && event == invalidEvent) {
511  IndexIntoFileItr indexItr(
513  indexItr.initializeRun();
514  return indexItr;
515  }
516 
517  std::vector<RunOrLumiIndexes>::const_iterator iRunEnd = std::upper_bound(iRun, phEnd, el, Compare_Index_Run());
518  if (!lumiMissing) {
519  std::vector<RunOrLumiIndexes>::const_iterator iLumi = std::lower_bound(iRun, iRunEnd, el);
520  if (iLumi == iRunEnd || iLumi->lumi() != lumi)
521  continue;
522 
523  if (event == invalidEvent) {
524  IndexIntoFileItr indexItr(this,
526  kRun,
527  iRun - runOrLumiIndexes().begin(),
528  iLumi - runOrLumiIndexes().begin(),
529  invalidIndex,
530  0,
531  0);
532  indexItr.initializeLumi();
533  return indexItr;
534  }
535 
536  long long beginEventNumbers = iLumi->beginEventNumbers();
537  long long endEventNumbers = iLumi->endEventNumbers();
538  if (beginEventNumbers >= endEventNumbers)
539  continue;
540 
541  long long indexToEvent = 0;
542  if (!eventEntries().empty()) {
543  std::vector<EventEntry>::const_iterator eventIter =
544  std::lower_bound(eventEntries().begin() + beginEventNumbers,
545  eventEntries().begin() + endEventNumbers,
546  EventEntry(event, invalidEntry));
547  if (eventIter == (eventEntries().begin() + endEventNumbers) || eventIter->event() != event)
548  continue;
549 
550  indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
551  } else {
553  std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(
554  eventNumbers().begin() + beginEventNumbers, eventNumbers().begin() + endEventNumbers, event);
555  if (eventIter == (eventNumbers().begin() + endEventNumbers) || *eventIter != event)
556  continue;
557 
558  indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
559  }
560 
561  int newIndexToLumi = iLumi - runOrLumiIndexes().begin();
562  while (runOrLumiEntries_[runOrLumiIndexes()[newIndexToLumi].indexToGetEntry()].entry() == invalidEntry) {
563  ++newIndexToLumi;
564  assert(static_cast<unsigned>(newIndexToLumi) < runOrLumiEntries_.size());
565  assert(runOrLumiIndexes()[newIndexToLumi].lumi() == lumi);
566  }
567 
568  return IndexIntoFileItr(this,
570  kRun,
571  iRun - runOrLumiIndexes().begin(),
572  newIndexToLumi,
573  iLumi - runOrLumiIndexes().begin(),
574  indexToEvent,
575  endEventNumbers - beginEventNumbers);
576  }
577  if (lumiMissing) {
578  std::vector<RunOrLumiIndexes>::const_iterator iLumi = iRun;
579  while (iLumi != iRunEnd && iLumi->lumi() == invalidLumi) {
580  ++iLumi;
581  }
582  if (iLumi == iRunEnd)
583  continue;
584 
585  std::vector<RunOrLumiIndexes>::const_iterator lumiEnd;
586  for (; iLumi != iRunEnd; iLumi = lumiEnd) {
587  RunOrLumiIndexes elWithLumi(phBegin->processHistoryIDIndex(), run, iLumi->lumi(), 0);
588  lumiEnd = std::upper_bound(iLumi, iRunEnd, elWithLumi);
589 
590  long long beginEventNumbers = iLumi->beginEventNumbers();
591  long long endEventNumbers = iLumi->endEventNumbers();
592  if (beginEventNumbers >= endEventNumbers)
593  continue;
594 
595  long long indexToEvent = 0;
596  if (!eventEntries().empty()) {
597  std::vector<EventEntry>::const_iterator eventIter =
598  std::lower_bound(eventEntries().begin() + beginEventNumbers,
599  eventEntries().begin() + endEventNumbers,
600  EventEntry(event, invalidEntry));
601  if (eventIter == (eventEntries().begin() + endEventNumbers) || eventIter->event() != event)
602  continue;
603  indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
604  } else {
606  std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(
607  eventNumbers().begin() + beginEventNumbers, eventNumbers().begin() + endEventNumbers, event);
608  if (eventIter == (eventNumbers().begin() + endEventNumbers) || *eventIter != event)
609  continue;
610  indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
611  }
612 
613  int newIndexToLumi = iLumi - runOrLumiIndexes().begin();
614  while (runOrLumiEntries_[runOrLumiIndexes()[newIndexToLumi].indexToGetEntry()].entry() == invalidEntry) {
615  ++newIndexToLumi;
616  assert(static_cast<unsigned>(newIndexToLumi) < runOrLumiEntries_.size());
617  assert(runOrLumiIndexes()[newIndexToLumi].lumi() == iLumi->lumi());
618  }
619 
620  return IndexIntoFileItr(this,
622  kRun,
623  iRun - runOrLumiIndexes().begin(),
624  newIndexToLumi,
625  iLumi - runOrLumiIndexes().begin(),
626  indexToEvent,
627  endEventNumbers - beginEventNumbers);
628  }
629  }
630  } // Loop over ProcessHistoryIDs
631 
633  }
634 
638  EventNumber_t event) const {
639  if (sortOrder == IndexIntoFile::numericalOrder) {
640  return findPosition(run, lumi, event); // a faster algorithm
641  }
642  IndexIntoFileItr itr = begin(sortOrder);
643  IndexIntoFileItr itrEnd = end(sortOrder);
644 
645  while (itr != itrEnd) {
646  if (itr.run() != run) {
647  itr.advanceToNextRun();
648  } else {
649  if (lumi == invalidLumi && event == invalidEvent) {
650  return itr;
651  } else if (lumi != invalidLumi && itr.peekAheadAtLumi() != lumi) {
652  if (!itr.skipLumiInRun()) {
653  itr.advanceToNextRun();
654  }
655  } else {
656  if (event == invalidEvent) {
657  return itr;
658  } else {
660  if (eventNumber == event) {
661  return itr;
662  } else {
663  if (!itr.skipToNextEventInLumi()) {
664  if (!itr.skipLumiInRun()) {
665  itr.advanceToNextRun();
666  }
667  }
668  }
669  }
670  }
671  }
672  }
673  return itrEnd;
674  }
675 
678  EventNumber_t event) const {
679  assert(event != invalidEvent);
680  IndexIntoFileItr iter = findPosition(run, lumi, event);
681  iter.advanceToEvent();
682  return iter;
683  }
684 
686  assert(lumi != invalidLumi);
687  IndexIntoFileItr iter = findPosition(run, lumi, 0U);
688  iter.advanceToLumi();
689  return iter;
690  }
691 
693  return findPosition(run, 0U, 0U);
694  }
695 
697  return (event != 0) ? containsEvent(run, lumi, event) : (lumi ? containsLumi(run, lumi) : containsRun(run));
698  }
699 
701  return findEventPosition(run, lumi, event).getEntryType() != kEnd;
702  }
703 
705  return findLumiPosition(run, lumi).getEntryType() != kEnd;
706  }
707 
709 
711 
713  return SortedRunOrLumiItr(this, runOrLumiEntries().size());
714  }
715 
717  std::set<IndexRunLumiEventKey>& intersection) const {
718  if (empty() || indexIntoFile.empty())
719  return;
721  indexIntoFile.fillRunOrLumiIndexes();
722  RunOrLumiIndexes const& back1 = runOrLumiIndexes().back();
723  RunOrLumiIndexes const& back2 = indexIntoFile.runOrLumiIndexes().back();
724 
725  // Very quick decision if the run ranges in the two files do not overlap
726  if (back2 < runOrLumiIndexes().front())
727  return;
728  if (back1 < indexIntoFile.runOrLumiIndexes().front())
729  return;
730 
733 
734  SortedRunOrLumiItr iter2 = indexIntoFile.beginRunOrLumi();
735  SortedRunOrLumiItr iEnd2 = indexIntoFile.endRunOrLumi();
736 
737  // Quick decision if the lumi ranges in the two files do not overlap
738  while (iter1 != iEnd1 && iter1.isRun())
739  ++iter1;
740  if (iter1 == iEnd1)
741  return;
742  if (back2 < iter1.runOrLumiIndexes())
743  return;
744 
745  while (iter2 != iEnd2 && iter2.isRun())
746  ++iter2;
747  if (iter2 == iEnd2)
748  return;
749  if (back1 < iter2.runOrLumiIndexes())
750  return;
751 
752  RunOrLumiIndexes const* previousIndexes = nullptr;
753 
754  // Loop through the both IndexIntoFile objects and look for matching lumis
755  while (iter1 != iEnd1 && iter2 != iEnd2) {
756  RunOrLumiIndexes const& indexes1 = iter1.runOrLumiIndexes();
757  RunOrLumiIndexes const& indexes2 = iter2.runOrLumiIndexes();
758  if (indexes1 < indexes2) {
759  ++iter1;
760  } else if (indexes2 < indexes1) {
761  ++iter2;
762  } else { // they are equal
763 
764  // Skip them if it is a run or the same lumi
765  if (indexes1.isRun() || (previousIndexes && !(*previousIndexes < indexes1))) {
766  ++iter1;
767  ++iter2;
768  } else {
769  previousIndexes = &indexes1;
770 
771  // Found a matching lumi, now look for matching events
772 
773  long long beginEventNumbers1 = indexes1.beginEventNumbers();
774  long long endEventNumbers1 = indexes1.endEventNumbers();
775 
776  long long beginEventNumbers2 = indexes2.beginEventNumbers();
777  long long endEventNumbers2 = indexes2.endEventNumbers();
778 
779  // there must be at least 1 event in each lumi for there to be any matches
780  if ((beginEventNumbers1 >= endEventNumbers1) || (beginEventNumbers2 >= endEventNumbers2)) {
781  ++iter1;
782  ++iter2;
783  continue;
784  }
785 
786  if (!eventEntries().empty() && !indexIntoFile.eventEntries().empty()) {
787  std::vector<EventEntry> matchingEvents;
788  std::insert_iterator<std::vector<EventEntry> > insertIter(matchingEvents, matchingEvents.begin());
789  std::set_intersection(eventEntries().begin() + beginEventNumbers1,
790  eventEntries().begin() + endEventNumbers1,
791  indexIntoFile.eventEntries().begin() + beginEventNumbers2,
792  indexIntoFile.eventEntries().begin() + endEventNumbers2,
793  insertIter);
794  for (EventEntry const& entry : matchingEvents) {
795  intersection.insert(IndexRunLumiEventKey(
796  indexes1.processHistoryIDIndex(), indexes1.run(), indexes1.lumi(), entry.event()));
797  }
798  } else {
800  indexIntoFile.fillEventNumbers();
801  std::vector<EventNumber_t> matchingEvents;
802  std::insert_iterator<std::vector<EventNumber_t> > insertIter(matchingEvents, matchingEvents.begin());
803  std::set_intersection(eventNumbers().begin() + beginEventNumbers1,
804  eventNumbers().begin() + endEventNumbers1,
805  indexIntoFile.eventNumbers().begin() + beginEventNumbers2,
806  indexIntoFile.eventNumbers().begin() + endEventNumbers2,
807  insertIter);
808  for (EventNumber_t const& eventNumber : matchingEvents) {
809  intersection.insert(
810  IndexRunLumiEventKey(indexes1.processHistoryIDIndex(), indexes1.run(), indexes1.lumi(), eventNumber));
811  }
812  }
813  }
814  }
815  }
816  }
817 
819  RunOrLumiIndexes const* previousIndexes = nullptr;
820 
821  for (SortedRunOrLumiItr iter = beginRunOrLumi(), iEnd = endRunOrLumi(); iter != iEnd; ++iter) {
822  RunOrLumiIndexes const& indexes = iter.runOrLumiIndexes();
823 
824  // Skip it if it is a run or the same lumi
825  if (indexes.isRun() || (previousIndexes && !(*previousIndexes < indexes))) {
826  continue;
827  }
828  previousIndexes = &indexes;
829 
830  long long beginEventNumbers = indexes.beginEventNumbers();
831  long long endEventNumbers = indexes.endEventNumbers();
832 
833  // there must be more than 1 event in the lumi for there to be any duplicates
834  if (beginEventNumbers + 1 >= endEventNumbers)
835  continue;
836 
837  if (!eventEntries().empty()) {
838  std::vector<EventEntry>::iterator last = eventEntries().begin() + endEventNumbers;
839  if (std::adjacent_find(eventEntries().begin() + beginEventNumbers, last) != last) {
840  return true;
841  }
842  } else {
844  std::vector<EventNumber_t>::iterator last = eventNumbers().begin() + endEventNumbers;
845  if (std::adjacent_find(eventNumbers().begin() + beginEventNumbers, last) != last) {
846  return true;
847  }
848  }
849  }
850  return false;
851  }
852 
854  : orderPHIDRun_(invalidEntry),
855  orderPHIDRunLumi_(invalidEntry),
856  entry_(invalidEntry),
857  processHistoryIDIndex_(invalidIndex),
858  run_(invalidRun),
859  lumi_(invalidLumi),
860  beginEvents_(invalidEntry),
861  endEvents_(invalidEntry) {}
862 
864  EntryNumber_t orderPHIDRunLumi,
866  int processHistoryIDIndex,
871  : orderPHIDRun_(orderPHIDRun),
872  orderPHIDRunLumi_(orderPHIDRunLumi),
873  entry_(entry),
874  processHistoryIDIndex_(processHistoryIDIndex),
875  run_(run),
876  lumi_(lumi),
877  beginEvents_(beginEvents),
878  endEvents_(endEvents) {}
879 
883  int indexToGetEntry)
884  : processHistoryIDIndex_(processHistoryIDIndex),
885  run_(run),
886  lumi_(lumi),
887  indexToGetEntry_(indexToGetEntry),
888  beginEventNumbers_(-1),
889  endEventNumbers_(-1) {}
890 
892  : indexIntoFile_(indexIntoFile), runOrLumi_(runOrLumi) {
893  assert(runOrLumi_ <= indexIntoFile_->runOrLumiEntries().size());
895  }
896 
898  return indexIntoFile_ == right.indexIntoFile() && runOrLumi_ == right.runOrLumi();
899  }
900 
902  return indexIntoFile_ != right.indexIntoFile() || runOrLumi_ != right.runOrLumi();
903  }
904 
906  if (runOrLumi_ != indexIntoFile_->runOrLumiEntries().size()) {
907  ++runOrLumi_;
908  }
909  return *this;
910  }
911 
913  return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).lumi() == invalidLumi;
914  }
915 
916  void IndexIntoFile::SortedRunOrLumiItr::getRange(long long& beginEventNumbers,
917  long long& endEventNumbers,
918  EntryNumber_t& beginEventEntry,
919  EntryNumber_t& endEventEntry) {
920  beginEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).beginEventNumbers();
921  endEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).endEventNumbers();
922 
923  int indexToGetEntry = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).indexToGetEntry();
924  beginEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).beginEvents();
925  endEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).endEvents();
926  }
927 
929  return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_);
930  }
931 
933  EntryType entryType,
934  int indexToRun,
935  int indexToLumi,
936  int indexToEventRange,
937  long long indexToEvent,
938  long long nEvents)
939  : indexIntoFile_(indexIntoFile),
940  size_(static_cast<int>(indexIntoFile_->runOrLumiEntries_.size())),
941  type_(entryType),
942  indexToRun_(indexToRun),
943  indexToLumi_(indexToLumi),
944  indexToEventRange_(indexToEventRange),
945  indexToEvent_(indexToEvent),
946  nEvents_(nEvents) {}
947 
949 
951  if (type_ == kEvent) {
952  if ((indexToEvent_ + 1) < nEvents_) {
953  ++indexToEvent_;
954  } else {
955  bool found = nextEventRange();
956 
957  if (!found) {
958  type_ = getRunOrLumiEntryType(indexToLumi_ + 1);
959 
960  if (type_ == kLumi) {
961  ++indexToLumi_;
962  initializeLumi();
963  } else if (type_ == kRun) {
964  indexToRun_ = indexToLumi_ + 1;
965  initializeRun();
966  } else {
967  setInvalid(); // type_ is kEnd
968  }
969  }
970  }
971  } else if (type_ == kLumi) {
972  if (indexToLumi_ + 1 == size_) {
973  if (indexToEvent_ < nEvents_) {
974  type_ = kEvent;
975  } else {
976  setInvalid();
977  }
978  } else {
979  EntryType nextType = getRunOrLumiEntryType(indexToLumi_ + 1);
980 
981  if (nextType == kLumi && isSameLumi(indexToLumi_, indexToLumi_ + 1)) {
982  ++indexToLumi_;
983  } else if (indexToEvent_ < nEvents_) {
984  type_ = kEvent;
985  } else if (nextType == kRun) {
986  type_ = kRun;
987  indexToRun_ = indexToLumi_ + 1;
988  initializeRun();
989  } else {
990  ++indexToLumi_;
991  initializeLumi();
992  }
993  }
994  } else if (type_ == kRun) {
995  EntryType nextType = getRunOrLumiEntryType(indexToRun_ + 1);
996  bool sameRun = isSameRun(indexToRun_, indexToRun_ + 1);
997  if (nextType == kRun && sameRun) {
998  ++indexToRun_;
999  } else if (nextType == kRun && !sameRun) {
1000  ++indexToRun_;
1001  initializeRun();
1002  } else if (nextType == kLumi) {
1003  type_ = kLumi;
1004  } else {
1005  setInvalid();
1006  }
1007  }
1008  }
1009 
1011  RunNumber_t& runOfSkippedEvent,
1012  LuminosityBlockNumber_t& lumiOfSkippedEvent,
1013  EntryNumber_t& skippedEventEntry) {
1014  if (indexToEvent_ < nEvents_) {
1015  phIndexOfSkippedEvent = processHistoryIDIndex();
1016  runOfSkippedEvent = run();
1017  lumiOfSkippedEvent = peekAheadAtLumi();
1018  skippedEventEntry = peekAheadAtEventEntry();
1019 
1020  if ((indexToEvent_ + 1) < nEvents_) {
1021  ++indexToEvent_;
1022  return;
1023  } else if (nextEventRange()) {
1024  return;
1025  } else if (type_ == kRun || type_ == kLumi) {
1026  if (skipLumiInRun()) {
1027  return;
1028  }
1029  } else if (type_ == kEvent) {
1030  next();
1031  return;
1032  }
1033  advanceToNextRun();
1034  return;
1035  }
1036 
1037  if (type_ == kRun) {
1038  while (skipLumiInRun()) {
1039  if (indexToEvent_ < nEvents_) {
1040  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1041  return;
1042  }
1043  }
1044  }
1045 
1046  while (indexToEvent_ >= nEvents_ && type_ != kEnd) {
1047  while (skipLumiInRun()) {
1048  if (indexToEvent_ < nEvents_) {
1049  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1050  return;
1051  }
1052  }
1053  advanceToNextRun();
1054  }
1055  if (type_ == kEnd) {
1056  phIndexOfSkippedEvent = invalidIndex;
1057  runOfSkippedEvent = invalidRun;
1058  lumiOfSkippedEvent = invalidLumi;
1059  skippedEventEntry = invalidEntry;
1060  return;
1061  }
1062  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1063  return;
1064  }
1065 
1067  RunNumber_t& runOfEvent,
1068  LuminosityBlockNumber_t& lumiOfEvent,
1069  EntryNumber_t& eventEntry) {
1070  // Look for previous events in the current lumi
1071  if (indexToEvent_ > 0) {
1072  --indexToEvent_;
1073  } else if (!previousEventRange()) {
1074  // Look for previous events in previous lumis
1075  if (!previousLumiWithEvents()) {
1076  // If we get here there are no previous events in the file
1077 
1078  if (!indexIntoFile_->empty()) {
1079  // Set the iterator to the beginning of the file
1080  type_ = kRun;
1081  indexToRun_ = 0;
1082  initializeRun();
1083  }
1084  phIndexOfEvent = invalidIndex;
1085  runOfEvent = invalidRun;
1086  lumiOfEvent = invalidLumi;
1087  eventEntry = invalidEntry;
1088  return;
1089  }
1090  }
1091  // Found a previous event and we have set the iterator so that this event
1092  // will be the next event process. (There may or may not be a run and/or
1093  // a lumi processed first).
1094  // Return information about this event
1095  phIndexOfEvent = processHistoryIDIndex();
1096  runOfEvent = run();
1097  lumiOfEvent = peekAheadAtLumi();
1098  eventEntry = peekAheadAtEventEntry();
1099  }
1100 
1102  // Find the correct place to start the search
1103  int newLumi = indexToLumi();
1104  if (newLumi == invalidIndex) {
1105  newLumi = indexToRun() == invalidIndex ? size() - 1 : indexToRun();
1106  } else {
1107  while (getRunOrLumiEntryType(newLumi - 1) == kLumi && isSameLumi(newLumi, newLumi - 1)) {
1108  --newLumi;
1109  }
1110  --newLumi;
1111  }
1112  if (newLumi <= 0)
1113  return false;
1114 
1115  // Look backwards for a lumi with events
1116  for (; newLumi > 0; --newLumi) {
1117  if (getRunOrLumiEntryType(newLumi) == kRun) {
1118  continue;
1119  }
1120  if (setToLastEventInRange(newLumi)) {
1121  break; // found it
1122  }
1123  }
1124  if (newLumi == 0)
1125  return false;
1126 
1127  // Finish initializing the iterator
1128  while (getRunOrLumiEntryType(newLumi - 1) == kLumi && isSameLumi(newLumi, newLumi - 1) &&
1129  lumiEntryValid(newLumi - 1)) {
1130  --newLumi;
1131  }
1132  setIndexToLumi(newLumi);
1133 
1134  if (type() != kEnd && isSameRun(newLumi, indexToRun())) {
1135  if (type() == kEvent)
1136  type_ = kLumi;
1137  return true;
1138  }
1139  int newRun = newLumi;
1140  while (newRun > 0 && getRunOrLumiEntryType(newRun - 1) == kLumi) {
1141  --newRun;
1142  }
1143  --newRun;
1144  assert(getRunOrLumiEntryType(newRun) == kRun);
1145  while (getRunOrLumiEntryType(newRun - 1) == kRun && isSameRun(newRun - 1, newLumi)) {
1146  --newRun;
1147  }
1148  indexToRun_ = newRun;
1149  type_ = kRun;
1150  return true;
1151  }
1152 
1154  if (indexToLumi() == invalidIndex)
1155  return invalidEntry;
1156 
1157  int saveIndexToLumi = indexToLumi();
1158  int saveIndexToEventRange = indexToEventRange();
1159  long long saveIndexToEvent = indexToEvent();
1160  long long saveNEvents = nEvents();
1161 
1162  initializeRun();
1163 
1165 
1166  do {
1167  if (indexToEvent() < nEvents()) {
1168  returnValue = peekAheadAtEventEntry();
1169  break;
1170  }
1171  } while (skipLumiInRun());
1172 
1173  setIndexToLumi(saveIndexToLumi);
1174  setIndexToEventRange(saveIndexToEventRange);
1175  setIndexToEvent(saveIndexToEvent);
1176  setNEvents(saveNEvents);
1177 
1178  return returnValue;
1179  }
1180 
1182  if (indexToLumi() == invalidIndex)
1183  return invalidEntry;
1184 
1185  int saveIndexToLumi = indexToLumi();
1186  int saveIndexToEventRange = indexToEventRange();
1187  long long saveIndexToEvent = indexToEvent();
1188  long long saveNEvents = nEvents();
1189 
1190  while (indexToLumi() - 1 > 0) {
1191  if (getRunOrLumiEntryType(indexToLumi() - 1) == kRun)
1192  break;
1193  if (!isSameLumi(indexToLumi(), indexToLumi() - 1))
1194  break;
1195  --indexToLumi_;
1196  }
1197  initializeLumi();
1198 
1200 
1201  if (indexToEvent() < nEvents()) {
1202  returnValue = peekAheadAtEventEntry();
1203  }
1204 
1205  setIndexToLumi(saveIndexToLumi);
1206  setIndexToEventRange(saveIndexToEventRange);
1207  setIndexToEvent(saveIndexToEvent);
1208  setNEvents(saveNEvents);
1209 
1210  return returnValue;
1211  }
1212 
1214  if (type_ == kEnd)
1215  return;
1216  for (int i = 1; indexToRun_ + i < size_; ++i) {
1217  if (getRunOrLumiEntryType(indexToRun_ + i) == kRun) {
1218  if (!isSameRun(indexToRun_, indexToRun_ + i)) {
1219  type_ = kRun;
1220  indexToRun_ += i;
1221  initializeRun();
1222  return;
1223  }
1224  }
1225  }
1226  setInvalid();
1227  }
1228 
1230  if (type_ == kEnd)
1231  return;
1232  assert(indexToRun_ != invalidIndex);
1233 
1234  // A preliminary step is to advance to the last run entry for
1235  // this run (actually this step is not needed in the
1236  // context I expect this to be called in, just being careful)
1237  int startSearch = indexToRun_;
1238  for (int i = 1; startSearch + i < size_; ++i) {
1239  if (getRunOrLumiEntryType(startSearch + i) == kRun && isSameRun(indexToRun_, startSearch + i)) {
1240  indexToRun_ = startSearch + i;
1241  } else {
1242  break;
1243  }
1244  }
1245 
1246  if (type_ == kRun && indexToLumi_ != invalidIndex) {
1247  type_ = kLumi;
1248  return;
1249  }
1250 
1251  startSearch = indexToLumi_;
1252  if (startSearch == invalidIndex)
1253  startSearch = indexToRun_;
1254  for (int i = 1; startSearch + i < size_; ++i) {
1255  if (getRunOrLumiEntryType(startSearch + i) == kRun) {
1256  if (!isSameRun(indexToRun_, startSearch + i)) {
1257  type_ = kRun;
1258  indexToRun_ = startSearch + i;
1259  initializeRun();
1260  return;
1261  }
1262  } else if (indexToLumi_ != invalidIndex) {
1263  if (!isSameLumi(indexToLumi_, startSearch + i)) {
1264  type_ = kLumi;
1265  indexToLumi_ = startSearch + i;
1266  initializeLumi();
1267  return;
1268  }
1269  }
1270  }
1271  setInvalid();
1272  }
1273 
1275  if (indexToEvent_ >= nEvents_)
1276  return false;
1277  if ((indexToEvent_ + 1) < nEvents_) {
1278  ++indexToEvent_;
1279  return true;
1280  }
1281  return nextEventRange();
1282  }
1283 
1285  indexToLumi_ = invalidIndex;
1286  indexToEventRange_ = invalidIndex;
1287  indexToEvent_ = 0;
1288  nEvents_ = 0;
1289 
1290  for (int i = 1; (i + indexToRun_) < size_; ++i) {
1291  EntryType entryType = getRunOrLumiEntryType(indexToRun_ + i);
1292  bool sameRun = isSameRun(indexToRun_, indexToRun_ + i);
1293 
1294  if (entryType == kRun) {
1295  if (sameRun) {
1296  continue;
1297  } else {
1298  break;
1299  }
1300  } else {
1301  indexToLumi_ = indexToRun_ + i;
1302  initializeLumi();
1303  return;
1304  }
1305  }
1306  }
1307 
1309  initializeLumi_();
1310  //See if entry number is invalid, this can happen if events from
1311  // different lumis overlap when doing concurrent lumi processing
1312  auto oldLumi = lumi();
1313  while (not lumiEntryValid(indexToLumi_)) {
1314  ++indexToLumi_;
1315  }
1316  assert(oldLumi == lumi());
1317  }
1318 
1320  return (indexIntoFile_ == right.indexIntoFile_ && size_ == right.size_ && type_ == right.type_ &&
1321  indexToRun_ == right.indexToRun_ && indexToLumi_ == right.indexToLumi_ &&
1322  indexToEventRange_ == right.indexToEventRange_ && indexToEvent_ == right.indexToEvent_ &&
1323  nEvents_ == right.nEvents_);
1324  }
1325 
1327  type_ = position.type_;
1328  indexToRun_ = position.indexToRun_;
1329  indexToLumi_ = position.indexToLumi_;
1330  indexToEventRange_ = position.indexToEventRange_;
1331  indexToEvent_ = position.indexToEvent_;
1332  nEvents_ = position.nEvents_;
1333  }
1334 
1335  void IndexIntoFile::IndexIntoFileItrImpl::getLumisInRun(std::vector<LuminosityBlockNumber_t>& lumis) const {
1336  lumis.clear();
1337 
1338  if (type_ == kEnd)
1339  return;
1340 
1341  LuminosityBlockNumber_t previousLumi = invalidLumi;
1342 
1343  for (int i = 1; (i + indexToRun_) < size_; ++i) {
1344  int index = i + indexToRun_;
1345  EntryType entryType = getRunOrLumiEntryType(index);
1346 
1347  if (entryType == kRun) {
1348  if (isSameRun(indexToRun_, index)) {
1349  continue;
1350  } else {
1351  break;
1352  }
1353  } else {
1354  LuminosityBlockNumber_t luminosityBlock = lumi(index);
1355  if (luminosityBlock != invalidLumi && luminosityBlock != previousLumi) {
1356  lumis.push_back(luminosityBlock);
1357  previousLumi = luminosityBlock;
1358  }
1359  }
1360  }
1361  std::sort(lumis.begin(), lumis.end());
1362  lumis.erase(std::unique(lumis.begin(), lumis.end()), lumis.end());
1363  }
1364 
1366  type_ = kEnd;
1367  indexToRun_ = invalidIndex;
1368  indexToLumi_ = invalidIndex;
1369  indexToEventRange_ = invalidIndex;
1370  indexToEvent_ = 0;
1371  nEvents_ = 0;
1372  }
1373 
1375  EntryType entryType,
1376  int indexToRun,
1377  int indexToLumi,
1378  int indexToEventRange,
1379  long long indexToEvent,
1380  long long nEvents)
1382  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents) {}
1383 
1385  return new IndexIntoFileItrNoSort(*this);
1386  }
1387 
1389  if (type() == kEnd)
1390  return invalidIndex;
1391  return indexIntoFile()->runOrLumiEntries()[indexToRun()].processHistoryIDIndex();
1392  }
1393 
1395  if (type() == kEnd)
1396  return invalidRun;
1397  return indexIntoFile()->runOrLumiEntries()[indexToRun()].run();
1398  }
1399 
1401  if (type() == kEnd || type() == kRun)
1402  return invalidLumi;
1403  return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
1404  }
1405 
1407  if (type() == kEnd)
1408  return invalidEntry;
1409  if (type() == kRun)
1410  return indexIntoFile()->runOrLumiEntries()[indexToRun()].entry();
1411  if (type() == kLumi)
1412  return indexIntoFile()->runOrLumiEntries()[indexToLumi()].entry();
1413  return indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() + indexToEvent();
1414  }
1415 
1417  if (indexToLumi() == invalidIndex)
1418  return invalidLumi;
1419  return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
1420  }
1421 
1423  if (indexToLumi() == invalidIndex)
1424  return invalidEntry;
1425  if (indexToEvent() >= nEvents())
1426  return invalidEntry;
1427  return indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() + indexToEvent();
1428  }
1429 
1431  assert(indexToLumi() != invalidIndex);
1432 
1433  setIndexToEventRange(invalidIndex);
1434  setIndexToEvent(0);
1435  setNEvents(0);
1436 
1437  for (int i = 0; indexToLumi() + i < size(); ++i) {
1438  if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].isRun()) {
1439  break;
1440  } else if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].lumi() ==
1441  indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
1442  if (indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].beginEvents() == invalidEntry) {
1443  continue;
1444  }
1445  setIndexToEventRange(indexToLumi() + i);
1446  setIndexToEvent(0);
1447  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1448  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1449  break;
1450  } else {
1451  break;
1452  }
1453  }
1454  }
1455 
1457  if (indexToEventRange() == invalidIndex)
1458  return false;
1459 
1460  // Look for the next event range, same lumi but different entry
1461  for (int i = 1; indexToEventRange() + i < size(); ++i) {
1462  if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].isRun()) {
1463  return false; // hit next run
1464  } else if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].lumi() ==
1465  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].lumi()) {
1466  if (indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].beginEvents() == invalidEntry) {
1467  continue; // same lumi but has no events, keep looking
1468  }
1469  setIndexToEventRange(indexToEventRange() + i);
1470  setIndexToEvent(0);
1471  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1472  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1473  return true; // found more events in this lumi
1474  }
1475  return false; // hit next lumi
1476  }
1477  return false; // hit the end of the IndexIntoFile
1478  }
1479 
1481  if (indexToEventRange() == invalidIndex)
1482  return false;
1483  assert(indexToEventRange() < size());
1484 
1485  // Look backward for a previous event range with events, same lumi but different entry
1486  for (int i = 1; indexToEventRange() - i > 0; ++i) {
1487  int newRange = indexToEventRange() - i;
1488  if (indexIntoFile()->runOrLumiEntries()[newRange].isRun()) {
1489  return false; // hit run
1490  } else if (isSameLumi(newRange, indexToEventRange())) {
1491  if (indexIntoFile()->runOrLumiEntries()[newRange].beginEvents() == invalidEntry) {
1492  continue; // same lumi but has no events, keep looking
1493  }
1494  setIndexToEventRange(newRange);
1495  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1496  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1497  setIndexToEvent(nEvents() - 1);
1498  return true; // found previous event in this lumi
1499  }
1500  return false; // hit previous lumi
1501  }
1502  return false; // hit the beginning of the IndexIntoFile, 0th entry has to be a run
1503  }
1504 
1506  if (indexIntoFile()->runOrLumiEntries()[index].beginEvents() == invalidEntry) {
1507  return false;
1508  }
1509  setIndexToEventRange(index);
1510  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1511  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1512  assert(nEvents() > 0);
1513  setIndexToEvent(nEvents() - 1);
1514  return true;
1515  }
1516 
1518  if (indexToLumi() == invalidIndex)
1519  return false;
1520  for (int i = 1; indexToLumi() + i < size(); ++i) {
1521  int newLumi = indexToLumi() + i;
1522  if (indexIntoFile()->runOrLumiEntries()[newLumi].isRun()) {
1523  return false; // hit next run
1524  } else if (indexIntoFile()->runOrLumiEntries()[newLumi].lumi() ==
1525  indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
1526  continue;
1527  }
1528  setIndexToLumi(newLumi);
1529  initializeLumi();
1530  return true; // hit next lumi
1531  }
1532  return false; // hit the end of the IndexIntoFile
1533  }
1534 
1536  return indexIntoFile()->runOrLumiEntries()[index].entry() != invalidEntry;
1537  }
1538 
1540  if (index < 0 || index >= size()) {
1541  return kEnd;
1542  } else if (indexIntoFile()->runOrLumiEntries()[index].isRun()) {
1543  return kRun;
1544  }
1545  return kLumi;
1546  }
1547 
1548  bool IndexIntoFile::IndexIntoFileItrNoSort::isSameLumi(int index1, int index2) const {
1549  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1550  return false;
1551  }
1552  return indexIntoFile()->runOrLumiEntries()[index1].lumi() == indexIntoFile()->runOrLumiEntries()[index2].lumi();
1553  }
1554 
1555  bool IndexIntoFile::IndexIntoFileItrNoSort::isSameRun(int index1, int index2) const {
1556  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1557  return false;
1558  }
1559  return indexIntoFile()->runOrLumiEntries()[index1].run() == indexIntoFile()->runOrLumiEntries()[index2].run() &&
1560  indexIntoFile()->runOrLumiEntries()[index1].processHistoryIDIndex() ==
1561  indexIntoFile()->runOrLumiEntries()[index2].processHistoryIDIndex();
1562  }
1563 
1565  if (index < 0 || index >= size()) {
1566  return invalidLumi;
1567  }
1568  return indexIntoFile()->runOrLumiEntries()[index].lumi();
1569  }
1570 
1572  EntryType entryType,
1573  int indexToRun,
1574  int indexToLumi,
1575  int indexToEventRange,
1576  long long indexToEvent,
1577  long long nEvents)
1579  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents) {
1580  indexIntoFile->fillRunOrLumiIndexes();
1581  }
1582 
1584  return new IndexIntoFileItrSorted(*this);
1585  }
1586 
1588  if (type() == kEnd)
1589  return invalidIndex;
1590  return indexIntoFile()->runOrLumiIndexes()[indexToRun()].processHistoryIDIndex();
1591  }
1592 
1594  if (type() == kEnd)
1595  return invalidRun;
1596  return indexIntoFile()->runOrLumiIndexes()[indexToRun()].run();
1597  }
1598 
1600  if (type() == kEnd || type() == kRun)
1601  return invalidLumi;
1602  return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
1603  }
1604 
1606  if (type() == kEnd)
1607  return invalidEntry;
1608  if (type() == kRun) {
1609  int i = indexIntoFile()->runOrLumiIndexes()[indexToRun()].indexToGetEntry();
1610  return indexIntoFile()->runOrLumiEntries()[i].entry();
1611  }
1612  if (type() == kLumi) {
1613  int i = indexIntoFile()->runOrLumiIndexes()[indexToLumi()].indexToGetEntry();
1614  return indexIntoFile()->runOrLumiEntries()[i].entry();
1615  }
1616  long long eventNumberIndex =
1617  indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() + indexToEvent();
1618  indexIntoFile()->fillEventEntries();
1619  return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
1620  }
1621 
1623  if (indexToLumi() == invalidIndex)
1624  return invalidLumi;
1625  return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
1626  }
1627 
1629  if (indexToLumi() == invalidIndex)
1630  return invalidEntry;
1631  if (indexToEvent() >= nEvents())
1632  return invalidEntry;
1633  long long eventNumberIndex =
1634  indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() + indexToEvent();
1635  indexIntoFile()->fillEventEntries();
1636  return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
1637  }
1638 
1640  assert(indexToLumi() != invalidIndex);
1641  setIndexToEventRange(indexToLumi());
1642  setIndexToEvent(0);
1643  setNEvents(indexIntoFile()->runOrLumiIndexes()[indexToLumi()].endEventNumbers() -
1644  indexIntoFile()->runOrLumiIndexes()[indexToLumi()].beginEventNumbers());
1645  if (nEvents() == 0) {
1646  setIndexToEventRange(invalidIndex);
1647  }
1648  }
1649 
1651 
1653 
1655  long long nEventsInRange = indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
1656  indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers();
1657  if (nEventsInRange == 0) {
1658  return false;
1659  }
1660  while (index > 0 && !indexIntoFile()->runOrLumiIndexes()[index - 1].isRun() && isSameLumi(index, index - 1)) {
1661  --index;
1662  }
1663  assert(nEventsInRange == indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
1664  indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers());
1665 
1666  setIndexToEventRange(index);
1667  setNEvents(nEventsInRange);
1668  assert(nEvents() > 0);
1669  setIndexToEvent(nEventsInRange - 1);
1670  return true;
1671  }
1672 
1674  if (indexToLumi() == invalidIndex)
1675  return false;
1676  for (int i = 1; indexToLumi() + i < size(); ++i) {
1677  int newLumi = indexToLumi() + i;
1678  if (indexIntoFile()->runOrLumiIndexes()[newLumi].isRun()) {
1679  return false; // hit next run
1680  } else if (indexIntoFile()->runOrLumiIndexes()[newLumi].lumi() ==
1681  indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi()) {
1682  continue;
1683  }
1684  setIndexToLumi(newLumi);
1685  initializeLumi();
1686  return true; // hit next lumi
1687  }
1688  return false; // hit the end of the IndexIntoFile
1689  }
1690 
1692  return indexIntoFile()->runOrLumiEntries()[indexIntoFile()->runOrLumiIndexes()[index].indexToGetEntry()].entry() !=
1693  invalidEntry;
1694  }
1695 
1697  if (index < 0 || index >= size()) {
1698  return kEnd;
1699  } else if (indexIntoFile()->runOrLumiIndexes()[index].isRun()) {
1700  return kRun;
1701  }
1702  return kLumi;
1703  }
1704 
1705  bool IndexIntoFile::IndexIntoFileItrSorted::isSameLumi(int index1, int index2) const {
1706  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1707  return false;
1708  }
1709  return indexIntoFile()->runOrLumiIndexes()[index1].lumi() == indexIntoFile()->runOrLumiIndexes()[index2].lumi();
1710  }
1711 
1712  bool IndexIntoFile::IndexIntoFileItrSorted::isSameRun(int index1, int index2) const {
1713  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1714  return false;
1715  }
1716  return indexIntoFile()->runOrLumiIndexes()[index1].run() == indexIntoFile()->runOrLumiIndexes()[index2].run() &&
1717  indexIntoFile()->runOrLumiIndexes()[index1].processHistoryIDIndex() ==
1718  indexIntoFile()->runOrLumiIndexes()[index2].processHistoryIDIndex();
1719  }
1720 
1722  if (index < 0 || index >= size()) {
1723  return invalidLumi;
1724  }
1725  return indexIntoFile()->runOrLumiIndexes()[index].lumi();
1726  }
1727 
1728  //*************************************
1730  EntryType entryType,
1731  int indexToRun,
1732  int indexToLumi,
1733  int indexToEventRange,
1734  long long indexToEvent,
1735  long long nEvents)
1737  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents) {
1738  auto const& runOrLumiEntries = this->indexIntoFile()->runOrLumiEntries();
1740  auto const itBegin = runOrLumiEntries.begin();
1741  auto itPresentEntryToRunOrLumis = runOrLumiEntries.begin();
1742  auto itRestartSearchAt = runOrLumiEntries.begin();
1743  EntryNumber_t endOfContiguousEventEntry = 0;
1744  std::vector<bool> usedEntry(runOrLumiEntries.size(), false);
1745  auto findFirstOpen = [](auto const& entries) {
1746  return std::find(entries.begin(), entries.end(), false) - entries.begin();
1747  };
1748  while (fileOrderRunOrLumiEntry_.size() != runOrLumiEntries.size()) {
1749  assert(itRestartSearchAt != runOrLumiEntries.end());
1750  assert(itPresentEntryToRunOrLumis != runOrLumiEntries.end());
1751 
1752  auto const index = itPresentEntryToRunOrLumis - itBegin;
1753  if (usedEntry[index]) {
1754  ++itPresentEntryToRunOrLumis;
1755  continue;
1756  }
1757  assert(static_cast<std::size_t>(index) < runOrLumiEntries.size());
1758  if (itPresentEntryToRunOrLumis->isRun()) {
1759  //take Run as it is
1760  fileOrderRunOrLumiEntry_.push_back(index);
1761  usedEntry[index] = true;
1762  itRestartSearchAt = runOrLumiEntries.begin() + findFirstOpen(usedEntry);
1763  itPresentEntryToRunOrLumis = itRestartSearchAt;
1764  continue;
1765  }
1766  auto const beginEvents = itPresentEntryToRunOrLumis->beginEvents();
1767  if (beginEvents == invalidEntry) {
1768  //this is an empty lumi. We want to preserve the order w.r.t previous entries
1769  if (std::find(usedEntry.begin(), usedEntry.begin() + index, false) == usedEntry.begin() + index) {
1770  fileOrderRunOrLumiEntry_.push_back(index);
1771  usedEntry[index] = true;
1772  itRestartSearchAt = runOrLumiEntries.begin() + findFirstOpen(usedEntry);
1773  itPresentEntryToRunOrLumis = itRestartSearchAt;
1774  continue;
1775  }
1776  } else if (beginEvents == endOfContiguousEventEntry) {
1777  fileOrderRunOrLumiEntry_.push_back(index);
1778  usedEntry[index] = true;
1779  endOfContiguousEventEntry = itPresentEntryToRunOrLumis->endEvents();
1780  itRestartSearchAt = runOrLumiEntries.begin() + findFirstOpen(usedEntry);
1781  itPresentEntryToRunOrLumis = itRestartSearchAt;
1782  continue;
1783  }
1784  ++itPresentEntryToRunOrLumis;
1785  }
1786  }
1787 
1789  return new IndexIntoFileItrEntryOrder(*this);
1790  }
1791 
1793  if (type() == kEnd)
1794  return invalidIndex;
1795  return runOrLumisEntry(indexToRun()).processHistoryIDIndex();
1796  }
1797 
1799  if (type() == kEnd)
1800  return invalidRun;
1801  return runOrLumisEntry(indexToRun()).run();
1802  }
1803 
1805  if (type() == kEnd || type() == kRun)
1806  return invalidLumi;
1807  return runOrLumisEntry(indexToLumi()).lumi();
1808  }
1809 
1811  if (type() == kEnd)
1812  return invalidEntry;
1813  if (type() == kRun)
1814  return runOrLumisEntry(indexToRun()).entry();
1815  if (type() == kLumi) {
1816  auto entry = runOrLumisEntry(indexToLumi()).entry();
1817  if (entry == invalidEntry) {
1818  if (indexToLumi() + 1 < size()) {
1819  if (runOrLumisEntry(indexToLumi()).lumi() != runOrLumisEntry(indexToLumi() + 1).lumi()) {
1820  //find the end of this lumi
1821  auto const& runLumiEntry = runOrLumisEntry(indexToLumi());
1822  for (auto nextIndex = indexToLumi() + 1; nextIndex < size(); ++nextIndex) {
1823  auto const& nextRunLumiEntry = runOrLumisEntry(nextIndex);
1824  if (runLumiEntry.lumi() == nextRunLumiEntry.lumi() and runLumiEntry.run() == nextRunLumiEntry.run() and
1825  runLumiEntry.processHistoryIDIndex() == nextRunLumiEntry.processHistoryIDIndex()) {
1826  auto nextEntry = nextRunLumiEntry.entry();
1827  if (nextEntry != invalidEntry) {
1828  return nextEntry;
1829  }
1830  }
1831  }
1832  return continuedLumi;
1833  }
1834  }
1835  }
1836  return entry;
1837  }
1838  return runOrLumisEntry(indexToEventRange()).beginEvents() + indexToEvent();
1839  }
1840 
1842  auto entry = runOrLumisEntry(indexToLumi()).entry();
1843  return entry == invalidEntry;
1844  }
1845 
1847  if (indexToLumi() == invalidIndex)
1848  return invalidLumi;
1849  return runOrLumisEntry(indexToLumi()).lumi();
1850  }
1851 
1853  if (indexToLumi() == invalidIndex)
1854  return invalidEntry;
1855  if (indexToEvent() >= nEvents())
1856  return invalidEntry;
1857  return runOrLumisEntry(indexToEventRange()).beginEvents() + indexToEvent();
1858  }
1859 
1861  assert(indexToLumi() != invalidIndex);
1862 
1863  setIndexToEventRange(invalidIndex);
1864  setIndexToEvent(0);
1865  setNEvents(0);
1866 
1867  for (int i = 0; indexToLumi() + i < size(); ++i) {
1868  if (runOrLumisEntry(indexToLumi() + i).isRun()) {
1869  break;
1870  } else if (runOrLumisEntry(indexToLumi() + i).lumi() == runOrLumisEntry(indexToLumi()).lumi()) {
1871  if (runOrLumisEntry(indexToLumi() + i).beginEvents() == invalidEntry) {
1872  continue;
1873  }
1874  setIndexToEventRange(indexToLumi() + i);
1875  setIndexToEvent(0);
1876  setNEvents(runOrLumisEntry(indexToEventRange()).endEvents() -
1877  runOrLumisEntry(indexToEventRange()).beginEvents());
1878  break;
1879  } else {
1880  break;
1881  }
1882  }
1883  }
1884 
1886  if (indexToEventRange() == invalidIndex)
1887  return false;
1888 
1889  // Look for the next event range, same lumi but different entry
1890  for (int i = 1; indexToEventRange() + i < size(); ++i) {
1891  if (runOrLumisEntry(indexToEventRange() + i).isRun()) {
1892  return false; // hit next run
1893  } else if (runOrLumisEntry(indexToEventRange() + i).lumi() == runOrLumisEntry(indexToEventRange()).lumi()) {
1894  if (runOrLumisEntry(indexToEventRange() + i).beginEvents() == invalidEntry) {
1895  continue; // same lumi but has no events, keep looking
1896  }
1897  setIndexToEventRange(indexToEventRange() + i);
1898  setIndexToEvent(0);
1899  setNEvents(runOrLumisEntry(indexToEventRange()).endEvents() -
1900  runOrLumisEntry(indexToEventRange()).beginEvents());
1901  return true; // found more events in this lumi
1902  }
1903  return false; // hit next lumi
1904  }
1905  return false; // hit the end of the IndexIntoFile
1906  }
1907 
1909  if (indexToEventRange() == invalidIndex)
1910  return false;
1911  assert(indexToEventRange() < size());
1912 
1913  // Look backward for a previous event range with events, same lumi but different entry
1914  for (int i = 1; indexToEventRange() - i > 0; ++i) {
1915  int newRange = indexToEventRange() - i;
1916  if (runOrLumisEntry(newRange).isRun()) {
1917  return false; // hit run
1918  } else if (isSameLumi(newRange, indexToEventRange())) {
1919  if (runOrLumisEntry(newRange).beginEvents() == invalidEntry) {
1920  continue; // same lumi but has no events, keep looking
1921  }
1922  setIndexToEventRange(newRange);
1923  setNEvents(runOrLumisEntry(indexToEventRange()).endEvents() -
1924  runOrLumisEntry(indexToEventRange()).beginEvents());
1925  setIndexToEvent(nEvents() - 1);
1926  return true; // found previous event in this lumi
1927  }
1928  return false; // hit previous lumi
1929  }
1930  return false; // hit the beginning of the IndexIntoFile, 0th entry has to be a run
1931  }
1932 
1934  if (runOrLumisEntry(index).beginEvents() == invalidEntry) {
1935  return false;
1936  }
1937  setIndexToEventRange(index);
1938  setNEvents(runOrLumisEntry(indexToEventRange()).endEvents() - runOrLumisEntry(indexToEventRange()).beginEvents());
1939  assert(nEvents() > 0);
1940  setIndexToEvent(nEvents() - 1);
1941  return true;
1942  }
1943 
1945  if (indexToLumi() == invalidIndex)
1946  return false;
1947  for (int i = 1; indexToLumi() + i < size(); ++i) {
1948  int newLumi = indexToLumi() + i;
1949  if (runOrLumisEntry(newLumi).isRun()) {
1950  return false; // hit next run
1951  } else if (runOrLumisEntry(newLumi).lumi() == runOrLumisEntry(indexToLumi()).lumi()) {
1952  continue;
1953  }
1954  setIndexToLumi(newLumi);
1955  initializeLumi();
1956  return true; // hit next lumi
1957  }
1958  return false; // hit the end of the IndexIntoFile
1959  }
1960 
1962  auto entry = runOrLumisEntry(index).entry();
1963  if (entry == invalidEntry) {
1964  if (index + 1 < size()) {
1965  if (runOrLumisEntry(index).lumi() != runOrLumisEntry(index + 1).lumi()) {
1966  return true;
1967  }
1968  }
1969  }
1970  return entry != invalidEntry;
1971  }
1972 
1974  if (index < 0 || index >= size()) {
1975  return kEnd;
1976  } else if (runOrLumisEntry(index).isRun()) {
1977  return kRun;
1978  }
1979  return kLumi;
1980  }
1981 
1982  bool IndexIntoFile::IndexIntoFileItrEntryOrder::isSameLumi(int index1, int index2) const {
1983  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1984  return false;
1985  }
1986  return runOrLumisEntry(index1).lumi() == runOrLumisEntry(index2).lumi();
1987  }
1988 
1989  bool IndexIntoFile::IndexIntoFileItrEntryOrder::isSameRun(int index1, int index2) const {
1990  if (index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1991  return false;
1992  }
1993  return runOrLumisEntry(index1).run() == runOrLumisEntry(index2).run() &&
1994  runOrLumisEntry(index1).processHistoryIDIndex() == runOrLumisEntry(index2).processHistoryIDIndex();
1995  }
1996 
1998  if (index < 0 || index >= size()) {
1999  return invalidLumi;
2000  }
2001  return runOrLumisEntry(index).lumi();
2002  }
2003 
2004  //*************************************
2005 
2007  SortOrder sortOrder,
2008  EntryType entryType,
2009  int indexToRun,
2010  int indexToLumi,
2011  int indexToEventRange,
2012  long long indexToEvent,
2013  long long nEvents)
2014  : impl_() {
2015  if (sortOrder == numericalOrder) {
2017  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents));
2018  swap(temp, impl_);
2019  } else if (sortOrder == firstAppearanceOrder) {
2021  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents));
2022  swap(temp, impl_);
2023  } else {
2025  indexIntoFile, entryType, indexToRun, indexToLumi, indexToEventRange, indexToEvent, nEvents));
2026  swap(temp, impl_);
2027  }
2028  }
2029 
2031  for (EntryType entryType = getEntryType(); entryType != kEnd && entryType != kEvent; entryType = getEntryType()) {
2032  impl_->next();
2033  }
2034  }
2035 
2037  for (EntryType entryType = getEntryType(); entryType != kEnd && entryType != kLumi; entryType = getEntryType()) {
2038  impl_->next();
2039  }
2040  }
2041 
2043  impl_->copyPosition(*position.impl_);
2044  }
2045 
2047  IndexIntoFile::RunOrLumiIndexes const& rh) {
2048  if (lh.processHistoryIDIndex() == rh.processHistoryIDIndex()) {
2049  return lh.run() < rh.run();
2050  }
2051  return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
2052  }
2053 
2055  return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
2056  }
2057 } // namespace edm
void initializeRun()
Should only be used internally and for tests.
void fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const
RunNumber_t & currentRun() const
LuminosityBlockNumber_t peekAheadAtLumi() const override
EntryType getRunOrLumiEntryType(int index) const override
EntryNumber_t peekAheadAtEventEntry() const
static constexpr int invalidIndex
EntryNumber_t entry() const override
IndexIntoFile const * indexIntoFile() const
bool isSameLumi(int index1, int index2) const override
IndexIntoFileItrEntryOrder(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
void addLumi(int index, RunNumber_t run, LuminosityBlockNumber_t lumi, EntryNumber_t entry)
std::vector< EventEntry > & eventEntries() const
Definition: Hash.h:43
bool lumiEntryValid(int index) const override
IndexIntoFileItrImpl * clone() const override
SortedRunOrLumiItr beginRunOrLumi() const
bool empty() const
True if no runs, lumis, or events are in the file.
LuminosityBlockNumber_t & currentLumi() const
def unique
Definition: tier0.py:24
bool operator==(SortedRunOrLumiItr const &right) const
bool lumiEntryValid(int index) const override
unsigned long long EventNumber_t
std::vector< RunOrLumiIndexes > & runOrLumiIndexes() const
__host__ __device__ constexpr RandomIt upper_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
void sortEvents() const
void fillUnsortedEventNumbers() const
EntryType getRunOrLumiEntryType(int index) const override
IndexIntoFileItr begin(SortOrder sortOrder) const
void swap(Hash< I > &other)
Definition: Hash.h:181
LuminosityBlockNumber_t lumi() const
std::map< IndexRunLumiKey, EntryNumber_t > & lumiToOrder() const
bool int lh
Definition: SIMDVec.h:20
std::vector< RunOrLumiEntry > const & runOrLumiEntries() const
Used internally and for test purposes.
void stable_sort_all(RandomAccessSequence &s)
wrappers for std::stable_sort
Definition: Algorithms.h:103
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
uint16_t size_type
unsigned int LuminosityBlockNumber_t
IndexIntoFileItr findRunPosition(RunNumber_t run) const
Same as findPosition.
std::vector< ProcessHistoryID > const & processHistoryIDs() const
static constexpr EventNumber_t invalidEvent
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
IndexIntoFileItr findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi=0U, EventNumber_t event=0U) const
int & previousAddedIndex() const
void sortVector_Run_Or_Lumi_Entries()
IndexIntoFileItrImpl * clone() const override
LuminosityBlockNumber_t lumi() const override
void setNumberOfEvents(EntryNumber_t nevents)
size_t numberOfEvents() const
void reduceProcessHistoryIDs(ProcessHistoryRegistry const &processHistoryRegistry)
IndexIntoFile const * indexIntoFile() const
int & currentIndex() const
long long EntryNumber_t
bool setToLastEventInRange(int index) override
IndexIntoFileItrImpl * clone() const override
RunOrLumiIndexes(int processHistoryIDIndex, RunNumber_t run, LuminosityBlockNumber_t lumi, int indexToGetEntry)
static constexpr EntryNumber_t continuedLumi
static constexpr RunNumber_t invalidRun
LuminosityBlockNumber_t peekAheadAtLumi() const override
void skipEventBackward(int &phIndexOfEvent, RunNumber_t &runOfEvent, LuminosityBlockNumber_t &lumiOfEvent, EntryNumber_t &eventEntry)
std::vector< RunOrLumiEntry > runOrLumiEntries_
LuminosityBlockNumber_t lumi() const override
void copyPosition(IndexIntoFileItr const &position)
Copy the position without modifying the pointer to the IndexIntoFile or size.
IndexIntoFileItr end(SortOrder sortOrder) const
Used to end an iteration over the Runs, Lumis, and Events in a file.
void skipEventForward(int &phIndexOfSkippedEvent, RunNumber_t &runOfSkippedEvent, LuminosityBlockNumber_t &lumiOfSkippedEvent, EntryNumber_t &skippedEventEntry)
std::vector< ProcessHistoryID > processHistoryIDs_
void fillEventEntries() const
IndexIntoFileItrImpl(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
LuminosityBlockNumber_t peekAheadAtLumi() const override
void fillRunOrLumiIndexes() const
bool operator==(IndexIntoFileItrImpl const &right) const
void set_intersection(IndexIntoFile const &indexIntoFile, std::set< IndexRunLumiEventKey > &intersection) const
bool isSameRun(int index1, int index2) const override
bool iterationWillBeInEntryOrder(SortOrder sortOrder) const
Used to determine whether or not to disable fast cloning.
void getLumisInRun(std::vector< LuminosityBlockNumber_t > &lumis) const
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
EntryNumber_t peekAheadAtEventEntry() const override
bool isSameRun(int index1, int index2) const override
std::vector< EntryNumber_t > fileOrderRunOrLumiEntry_
bool operator()(IndexIntoFile::RunOrLumiIndexes const &lh, IndexIntoFile::RunOrLumiIndexes const &rh)
list lumi
Definition: dqmdumpme.py:53
bool operator!=(SortedRunOrLumiItr const &right) const
void addEntry(ProcessHistoryID const &processHistoryID, RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry)
SortedRunOrLumiItr(IndexIntoFile const *indexIntoFile, unsigned runOrLumi)
Hash< ProcessHistoryType > ProcessHistoryID
void sortEventEntries() const
bool containsLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) const
bool containsDuplicateEvents() const
Returns true if the IndexIntoFile contains 2 events with the same ProcessHistoryID index...
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
void fixIndexes(std::vector< ProcessHistoryID > &processHistoryIDs)
EntryNumber_t peekAheadAtEventEntry() const override
bool setToLastEventInRange(int index) override
void resetEventFinder() const
static constexpr EntryNumber_t invalidEntry
IndexIntoFileItrSorted(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
std::vector< EventNumber_t > & unsortedEventNumbers()
static constexpr LuminosityBlockNumber_t invalidLumi
IndexIntoFileItr findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const
void initializeLumi()
Should only be used internally and for tests.
ProcessHistoryID const & processHistoryID(int i) const
std::map< IndexRunKey, EntryNumber_t > & runToOrder() const
void copyPosition(IndexIntoFileItrImpl const &position)
LuminosityBlockNumber_t lumi() const override
void doneFileInitialization()
Clears the temporary vector of event numbers to reduce memory usage.
EntryType getRunOrLumiEntryType(int index) const override
EventNumber_t getEventNumberOfEntry(EntryNumber_t entry) const
__host__ __device__ constexpr RandomIt lower_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
void fillEventNumbers() const
static int position[264][3]
Definition: ReadPGInfo.cc:289
bool isSameLumi(int index1, int index2) const override
bool isSameRun(int index1, int index2) const override
bool isSameLumi(int index1, int index2) const override
list entry
Definition: mps_splice.py:68
bool lumiEntryValid(int index) const override
bool containsEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
std::vector< EventNumber_t > & eventNumbers() const
IndexIntoFileItr(IndexIntoFile const *indexIntoFile, SortOrder sortOrder, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
unsigned int RunNumber_t
SortedRunOrLumiItr endRunOrLumi() const
tuple last
Definition: dqmdumpme.py:56
bool operator()(IndexIntoFile::RunOrLumiIndexes const &lh, IndexIntoFile::RunOrLumiIndexes const &rh)
EntryNumber_t entry() const override
std::vector< EventNumber_t > & unsortedEventNumbersMutable() const
bool containsRun(RunNumber_t run) const
IndexIntoFileItr findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
void getRange(long long &beginEventNumbers, long long &endEventNumbers, EntryNumber_t &beginEventEntry, EntryNumber_t &endEventEntry)
EntryNumber_t & endEvents() const
LuminosityBlockNumber_t peekAheadAtLumi() const
EntryNumber_t & beginEvents() const
value_ptr< IndexIntoFileItrImpl > impl_
tuple size
Write out results.
IndexIntoFileItrNoSort(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
EntryNumber_t peekAheadAtEventEntry() const override
RunOrLumiIndexes const & runOrLumiIndexes() const
std::vector< std::string > set_intersection(std::vector< std::string > const &v1, std::vector< std::string > const &v2)