1010#include < TClass.h>
1111
1212#include < cassert>
13- #include < iostream>
1413#include < limits>
1514
1615namespace edm {
@@ -121,11 +120,12 @@ namespace edm {
121120 return index;
122121 }
123122 // Now check to see if only one process has this type/module/instance name
124- auto nextIndex = index + 1 ;
123+ // we need to skip the skipCurrentProcess entry
124+ auto nextIndex = index + 2 ;
125125 while (indexAndNames_.size () > nextIndex && indexAndNames_[nextIndex].startInProcessNames () != 0U ) {
126126 ++nextIndex;
127127 }
128- return (nextIndex == index + 2 ) ? index + 1 : index;
128+ return (nextIndex == index + 3 ) ? index + 2 : index;
129129 };
130130
131131 return indexAndNames_[checkForSingleProcess (iToIndexAndNames)].index ();
@@ -201,23 +201,6 @@ namespace edm {
201201 return Matches (this , startInIndexAndNames, numberOfMatches);
202202 }
203203
204- ProductResolverIndexHelper::Matches ProductResolverIndexHelper::relatedIndexes (KindOfType kindOfType,
205- TypeID const & typeID) const {
206- unsigned int startInIndexAndNames = std::numeric_limits<unsigned int >::max ();
207- unsigned int numberOfMatches = 0 ;
208-
209- // Look for the type and check to see if it found it
210- unsigned iType = indexToType (kindOfType, typeID);
211- if (iType != std::numeric_limits<unsigned int >::max ()) {
212- // Get the range of entries with a matching TypeID
213- Range const & range = ranges_[iType];
214-
215- startInIndexAndNames = range.begin ();
216- numberOfMatches = range.end () - range.begin ();
217- }
218- return Matches (this , startInIndexAndNames, numberOfMatches);
219- }
220-
221204 ProductResolverIndex ProductResolverIndexHelper::insert (TypeID const & typeID,
222205 char const * moduleLabel,
223206 char const * instance,
@@ -252,8 +235,11 @@ namespace edm {
252235 item.clearProcess ();
253236 iter = items_->find (item);
254237 if (iter == items_->end ()) {
255- item.setIndex (nextIndexValue_);
256- ++nextIndexValue_;
238+ item.setIndex (ProductResolverIndexInitializing);
239+ items_->insert (item);
240+ // add entry for skipCurrentProcess
241+ item.setSkipCurrentProcess ();
242+ item.setIndex (ProductResolverIndexInitializing);
257243 items_->insert (item);
258244 }
259245
@@ -273,8 +259,10 @@ namespace edm {
273259 containedItem.clearProcess ();
274260 iter = items_->find (containedItem);
275261 if (iter == items_->end ()) {
276- containedItem.setIndex (nextIndexValue_);
277- ++nextIndexValue_;
262+ containedItem.setIndex (ProductResolverIndexInitializing);
263+ items_->insert (containedItem);
264+ containedItem.setSkipCurrentProcess ();
265+ containedItem.setIndex (ProductResolverIndexInitializing);
278266 items_->insert (containedItem);
279267 }
280268
@@ -292,8 +280,10 @@ namespace edm {
292280 baseItem.clearProcess ();
293281 iter = items_->find (baseItem);
294282 if (iter == items_->end ()) {
295- baseItem.setIndex (nextIndexValue_);
296- ++nextIndexValue_;
283+ baseItem.setIndex (ProductResolverIndexInitializing);
284+ items_->insert (baseItem);
285+ baseItem.setSkipCurrentProcess ();
286+ baseItem.setIndex (ProductResolverIndexInitializing);
297287 items_->insert (baseItem);
298288 }
299289 }
@@ -317,7 +307,67 @@ namespace edm {
317307 return insert (typeID, moduleLabel, instance, process, containedTypeID, baseTypesOfContainedType);
318308 }
319309
320- void ProductResolverIndexHelper::setFrozen (std::string_view processName) {
310+ namespace {
311+ void setNoProcessIndices (std::vector<edm::ProductResolverIndexHelper::IndexAndNames>::iterator itBegin,
312+ std::vector<edm::ProductResolverIndexHelper::IndexAndNames>::iterator itEnd,
313+ std::vector<std::string> const & orderedProcessNames,
314+ std::vector<char > const & processNames) {
315+ using IndexAndNames = edm::ProductResolverIndexHelper::IndexAndNames;
316+ assert (itEnd - itBegin > 2 );
317+ assert (itBegin->startInProcessNames () == 0U );
318+ assert ((itBegin + 1 )->startInProcessNames () == 1U );
319+ assert (processNames[(itBegin + 1 )->startInProcessNames ()] == ' #' );
320+ assert (itBegin->index () == edm::ProductResolverIndexInitializing);
321+ assert ((itBegin + 1 )->index () == edm::ProductResolverIndexInitializing);
322+ if (itEnd - itBegin == 3 ) {
323+ // only have one actual process
324+ *itBegin =
325+ IndexAndNames ((itBegin + 2 )->index (), itBegin->startInBigNamesContainer (), itBegin->startInProcessNames ());
326+ // Now handle skipCurrentProcess
327+ if (orderedProcessNames[0 ] == &processNames[(itBegin + 2 )->startInProcessNames ()]) {
328+ // the one process is the current process
329+ *(itBegin + 1 ) = IndexAndNames (ProductResolverIndexInvalid,
330+ (itBegin + 1 )->startInBigNamesContainer (),
331+ (itBegin + 1 )->startInProcessNames ());
332+ } else {
333+ *(itBegin + 1 ) = IndexAndNames (
334+ (itBegin + 2 )->index (), (itBegin + 1 )->startInBigNamesContainer (), (itBegin + 1 )->startInProcessNames ());
335+ }
336+ } else {
337+ bool foundFirstMatch = false ;
338+ for (auto const & proc : orderedProcessNames) {
339+ auto it = itBegin + 2 ;
340+ while (it != itEnd && proc != &processNames[it->startInProcessNames ()]) {
341+ ++it;
342+ }
343+ if (it != itEnd) {
344+ if (not foundFirstMatch) {
345+ foundFirstMatch = true ;
346+ // found a process that matches
347+ *itBegin =
348+ IndexAndNames (it->index (), itBegin->startInBigNamesContainer (), itBegin->startInProcessNames ());
349+ // Now handle skipCurrentProcess
350+ if (proc != orderedProcessNames[0 ]) {
351+ *(itBegin + 1 ) = IndexAndNames (
352+ it->index (), (itBegin + 1 )->startInBigNamesContainer (), (itBegin + 1 )->startInProcessNames ());
353+ break ;
354+ } else {
355+ // this process is the current process
356+ *(itBegin + 1 ) = IndexAndNames (ProductResolverIndexInvalid,
357+ (itBegin + 1 )->startInBigNamesContainer (),
358+ (itBegin + 1 )->startInProcessNames ());
359+ }
360+ } else {
361+ *(itBegin + 1 ) = IndexAndNames (
362+ it->index (), (itBegin + 1 )->startInBigNamesContainer (), (itBegin + 1 )->startInProcessNames ());
363+ break ;
364+ }
365+ }
366+ }
367+ }
368+ }
369+ } // namespace
370+ void ProductResolverIndexHelper::setFrozen (std::vector<std::string> const & orderedProcessNames) {
321371 if (!items_)
322372 return ;
323373
@@ -361,6 +411,15 @@ namespace edm {
361411 previousInstance = item.instance ();
362412 }
363413
414+ // sanity check
415+ for (auto const & p : *processItems_) {
416+ if (p.empty () or p == " #" )
417+ continue ;
418+ if (orderedProcessNames.end () == std::find (orderedProcessNames.begin (), orderedProcessNames.end (), p)) {
419+ throw Exception (errors::LogicError)
420+ << " ProductResolverIndexHelper::setFrozen process not in ordered list " << p << std::endl;
421+ }
422+ }
364423 // Size and fill the process name vector
365424 unsigned int processNamesSize = 0 ;
366425 for (auto const & processItem : *processItems_) {
@@ -374,9 +433,6 @@ namespace edm {
374433 }
375434 processNames_.push_back (' \0 ' );
376435 lookupProcessNames_.push_back (processItem);
377- if (processItem == processName) {
378- producesInCurrentProcess_ = true ;
379- }
380436 }
381437
382438 // Reserve memory in the vectors
@@ -393,9 +449,10 @@ namespace edm {
393449 unsigned int iBeginning = 0 ;
394450 iCountCharacters = 0 ;
395451 unsigned int previousCharacterCount = 0 ;
452+ unsigned int iNoProcessBegin = 0 ;
396453 if (!items_->empty ()) {
397454 for (auto const & item : *items_) {
398- if (iFirstThisType || item.typeID () != previousTypeID || item.kindOfType () != previousKindOfType) {
455+ if (iFirstType || item.typeID () != previousTypeID || item.kindOfType () != previousKindOfType) {
399456 iFirstThisType = true ;
400457 sortedTypeIDs_.push_back (item.typeID ());
401458 if (iFirstType) {
@@ -405,9 +462,15 @@ namespace edm {
405462 }
406463 iBeginning = iCount;
407464 }
408- ++iCount;
409465
410466 if (iFirstThisType || item.moduleLabel () != previousModuleLabel || item.instance () != previousInstance) {
467+ if (iNoProcessBegin != iCount) {
468+ setNoProcessIndices (indexAndNames_.begin () + iNoProcessBegin,
469+ indexAndNames_.begin () + iCount,
470+ orderedProcessNames,
471+ processNames_);
472+ iNoProcessBegin = iCount;
473+ }
411474 unsigned int labelSize = item.moduleLabel ().size ();
412475 for (unsigned int j = 0 ; j < labelSize; ++j) {
413476 bigNamesContainer_.push_back (item.moduleLabel ()[j]);
@@ -439,8 +502,11 @@ namespace edm {
439502 previousKindOfType = item.kindOfType ();
440503 previousModuleLabel = item.moduleLabel ();
441504 previousInstance = item.instance ();
505+ ++iCount;
442506 }
443507 ranges_.push_back (Range (iBeginning, iCount));
508+ setNoProcessIndices (
509+ indexAndNames_.begin () + iNoProcessBegin, indexAndNames_.end (), orderedProcessNames, processNames_);
444510 }
445511
446512 // Some sanity checks to protect against out of bounds vector accesses
@@ -616,30 +682,50 @@ namespace edm {
616682
617683 void ProductResolverIndexHelper::sanityCheck () const {
618684 bool sanityChecksPass = true ;
619- if (sortedTypeIDs_.size () != ranges_.size ())
685+ std::string errorMessage;
686+ if (sortedTypeIDs_.size () != ranges_.size ()) {
620687 sanityChecksPass = false ;
688+ errorMessage += " sortedTypeIDs_.size() != ranges_.size()\n " ;
689+ }
621690
622691 unsigned int previousEnd = 0 ;
623692 for (auto const & range : ranges_) {
624- if (range.begin () != previousEnd)
693+ if (range.begin () != previousEnd) {
625694 sanityChecksPass = false ;
626- if (range.begin () >= range.end ())
695+ errorMessage += " ranges_ are not contiguous\n " ;
696+ }
697+ if (range.begin () >= range.end ()) {
627698 sanityChecksPass = false ;
699+ errorMessage += " ranges_ are not valid\n " ;
700+ }
628701 previousEnd = range.end ();
629702 }
630- if (previousEnd != indexAndNames_.size ())
703+ if (previousEnd != indexAndNames_.size ()) {
631704 sanityChecksPass = false ;
705+ errorMessage += " ranges_ do not cover all of indexAndNames_\n " ;
706+ }
632707
633708 unsigned maxStart = 0 ;
634709 unsigned maxStartProcess = 0 ;
635710 for (auto const & indexAndName : indexAndNames_) {
636- if (indexAndName.index () >= nextIndexValue_ && indexAndName.index () != ProductResolverIndexAmbiguous)
711+ if (indexAndName.index () >= nextIndexValue_ && (indexAndName.index () != ProductResolverIndexAmbiguous and
712+ indexAndName.index () != ProductResolverIndexInvalid)) {
637713 sanityChecksPass = false ;
714+ auto startOfModule = indexAndName.startInBigNamesContainer ();
715+ auto startOfInstance = strlen (&bigNamesContainer_[startOfModule]) + 1 + startOfModule;
716+ errorMessage += " indexAndNames_ has invalid index" + std::to_string (indexAndName.index ()) + " " +
717+ &bigNamesContainer_[startOfModule] + " " + &bigNamesContainer_[startOfInstance] + " " +
718+ &processNames_[indexAndName.startInProcessNames ()] + " \n " ;
719+ }
638720
639- if (indexAndName.startInBigNamesContainer () >= bigNamesContainer_.size ())
721+ if (indexAndName.startInBigNamesContainer () >= bigNamesContainer_.size ()) {
640722 sanityChecksPass = false ;
641- if (indexAndName.startInProcessNames () >= processNames_.size ())
723+ errorMessage += " indexAndNames_ has invalid startInBigNamesContainer\n " ;
724+ }
725+ if (indexAndName.startInProcessNames () >= processNames_.size ()) {
642726 sanityChecksPass = false ;
727+ errorMessage += " indexAndNames_ has invalid startInProcessNames\n " ;
728+ }
643729
644730 if (indexAndName.startInBigNamesContainer () > maxStart)
645731 maxStart = indexAndName.startInBigNamesContainer ();
@@ -648,34 +734,47 @@ namespace edm {
648734 }
649735
650736 if (!indexAndNames_.empty ()) {
651- if (bigNamesContainer_.back () != ' \0 ' )
737+ if (bigNamesContainer_.back () != ' \0 ' ) {
652738 sanityChecksPass = false ;
653- if (processNames_.back () != ' \0 ' )
739+ errorMessage += " bigNamesContainer_ does not end with null char\n " ;
740+ }
741+ if (processNames_.back () != ' \0 ' ) {
654742 sanityChecksPass = false ;
655- if (maxStart >= bigNamesContainer_.size ())
743+ errorMessage += " processNames_ does not end with null char\n " ;
744+ }
745+ if (maxStart >= bigNamesContainer_.size ()) {
656746 sanityChecksPass = false ;
747+ errorMessage += " maxStart >= bigNamesContainer_.size()\n " ;
748+ }
657749 unsigned int countZeroes = 0 ;
658750 for (unsigned j = maxStart; j < bigNamesContainer_.size (); ++j) {
659751 if (bigNamesContainer_[j] == ' \0 ' ) {
660752 ++countZeroes;
661753 }
662754 }
663- if (countZeroes != 2 )
755+ if (countZeroes != 2 ) {
664756 sanityChecksPass = false ;
665- if (maxStartProcess >= processNames_.size ())
757+ errorMessage += " bigNamesContainer_ does not have two null chars\n " ;
758+ }
759+ if (maxStartProcess >= processNames_.size ()) {
666760 sanityChecksPass = false ;
761+ errorMessage += " maxStartProcess >= processNames_.size()\n " ;
762+ }
667763 countZeroes = 0 ;
668764 for (unsigned j = maxStartProcess; j < processNames_.size (); ++j) {
669765 if (processNames_[j] == ' \0 ' ) {
670766 ++countZeroes;
671767 }
672768 }
673- if (countZeroes != 1 )
769+ if (countZeroes != 1 ) {
674770 sanityChecksPass = false ;
771+ errorMessage += " processNames_ does not have one null char\n " ;
772+ }
675773 }
676774
677775 if (!sanityChecksPass) {
678- throw Exception (errors::LogicError) << " ProductResolverIndexHelper::setFrozen - Detected illegal state.\n " ;
776+ throw Exception (errors::LogicError) << " ProductResolverIndexHelper::setFrozen - Detected illegal state.\n "
777+ << errorMessage;
679778 }
680779 }
681780
@@ -769,8 +868,8 @@ namespace edm {
769868 if (items_) {
770869 os << " ******* items_ \n " ;
771870 for (auto const & item : *items_) {
772- std::cout << item.kindOfType () << " " << item.moduleLabel () << " " << item.instance () << " " << item.process ()
773- << " " << item.index () << " " << item.typeID () << " \n " ;
871+ os << item.kindOfType () << " " << item.moduleLabel () << " " << item.instance () << " " << item.process () << " "
872+ << item.index () << " " << item.typeID () << " \n " ;
774873 }
775874 }
776875 if (processItems_) {
0 commit comments