File indexing completed on 2024-04-06 12:05:05
0001
0002 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0003 #include "DataFormats/Provenance/interface/ViewTypeChecker.h"
0004 #include "FWCore/Reflection/interface/DictionaryTools.h"
0005 #include "FWCore/Utilities/interface/EDMException.h"
0006 #include "FWCore/Reflection/interface/TypeWithDict.h"
0007 #include "FWCore/Utilities/interface/WrappedClassName.h"
0008 #include "FWCore/Utilities/interface/getAnyPtr.h"
0009
0010 #include <TClass.h>
0011
0012 #include <cassert>
0013 #include <iostream>
0014 #include <limits>
0015
0016 namespace edm {
0017
0018 namespace productholderindexhelper {
0019 TypeID getContainedTypeFromWrapper(TypeID const& wrappedTypeID, std::string const& className) {
0020 static int const vtcOffset =
0021 TClass::GetClass("edm::WrapperBase")->GetBaseClassOffset(TClass::GetClass("edm::ViewTypeChecker"));
0022 static TClass const* const wbClass = TClass::GetClass("edm::WrapperBase");
0023 static std::string const refVector("edm::RefVector<");
0024 static std::string const refToBaseVector("edm::RefToBaseVector<");
0025 static std::string const ptrVector("edm::PtrVector<");
0026 static std::string const vectorPtr("std::vector<edm::Ptr<");
0027 static std::string const vectorUniquePtr("std::vector<std::unique_ptr<");
0028 static std::string const associationMap("edm::AssociationMap<");
0029 static std::string const newDetSetVector("edmNew::DetSetVector<");
0030 static size_t const rvsize = refVector.size();
0031 static size_t const rtbvsize = refToBaseVector.size();
0032 static size_t const pvsize = ptrVector.size();
0033 static size_t const vpsize = vectorPtr.size();
0034 static size_t const vupsize = vectorUniquePtr.size();
0035 static size_t const amsize = associationMap.size();
0036 static size_t const ndsize = newDetSetVector.size();
0037 bool mayBeRefVector = (className.substr(0, rvsize) == refVector) ||
0038 (className.substr(0, rtbvsize) == refToBaseVector) ||
0039 (className.substr(0, pvsize) == ptrVector) || (className.substr(0, vpsize) == vectorPtr) ||
0040 (className.substr(0, vupsize) == vectorUniquePtr);
0041
0042
0043
0044
0045
0046
0047
0048 if (className.substr(0, amsize) == associationMap || className.substr(0, ndsize) == newDetSetVector) {
0049 return TypeID(typeid(void));
0050 }
0051 TClass* cl = TClass::GetClass(wrappedTypeID.className().c_str());
0052 if (cl == nullptr) {
0053 return TypeID(typeid(void));
0054 }
0055 void* p = cl->New();
0056 int offset = cl->GetBaseClassOffset(wbClass) + vtcOffset;
0057 std::unique_ptr<ViewTypeChecker> checker = getAnyPtr<ViewTypeChecker>(p, offset);
0058 if (mayBeRefVector) {
0059 std::type_info const& ti = checker->memberTypeInfo();
0060 if (ti != typeid(void)) {
0061 return TypeID(ti);
0062 }
0063 }
0064 return TypeID(checker->valueTypeInfo());
0065 }
0066
0067 TypeID getContainedType(TypeID const& typeID) {
0068 const std::string& className = typeID.className();
0069 TypeWithDict const wrappedType = TypeWithDict::byName(wrappedClassName(className));
0070 TypeID const wrappedTypeID = TypeID(wrappedType.typeInfo());
0071 return getContainedTypeFromWrapper(wrappedTypeID, className);
0072 }
0073
0074 bool typeIsViewCompatible(TypeID const& requestedViewType,
0075 TypeID const& wrappedtypeID,
0076 std::string const& className) {
0077 auto elementType = getContainedTypeFromWrapper(wrappedtypeID, className);
0078 if (elementType == TypeID(typeid(void)) or elementType == TypeID()) {
0079
0080 return false;
0081 }
0082 if (elementType == requestedViewType) {
0083 return true;
0084 }
0085
0086 std::vector<std::string> missingDictionaries;
0087 std::vector<TypeID> baseTypes;
0088 if (!public_base_classes(missingDictionaries, elementType, baseTypes)) {
0089 return false;
0090 }
0091 for (auto const& base : baseTypes) {
0092 if (TypeID(base.typeInfo()) == requestedViewType) {
0093 return true;
0094 }
0095 }
0096 return false;
0097 }
0098
0099 }
0100
0101 ProductResolverIndexHelper::ProductResolverIndexHelper()
0102 : nextIndexValue_(0),
0103 beginElements_(0),
0104 items_(new std::set<ProductResolverIndexHelper::Item>),
0105 processItems_(new std::set<std::string>) {}
0106
0107 ProductResolverIndex ProductResolverIndexHelper::index(KindOfType kindOfType,
0108 TypeID const& typeID,
0109 char const* moduleLabel,
0110 char const* instance,
0111 char const* process) const {
0112 unsigned int iToIndexAndNames = indexToIndexAndNames(kindOfType, typeID, moduleLabel, instance, process);
0113
0114 if (iToIndexAndNames == std::numeric_limits<unsigned int>::max()) {
0115 return ProductResolverIndexInvalid;
0116 }
0117 return indexAndNames_[iToIndexAndNames].index();
0118 }
0119
0120 ProductResolverIndexHelper::Matches::Matches(ProductResolverIndexHelper const* productResolverIndexHelper,
0121 unsigned int startInIndexAndNames,
0122 unsigned int numberOfMatches)
0123 : productResolverIndexHelper_(productResolverIndexHelper),
0124 startInIndexAndNames_(startInIndexAndNames),
0125 numberOfMatches_(numberOfMatches) {
0126 if (numberOfMatches != 0 &&
0127 startInIndexAndNames_ + numberOfMatches_ > productResolverIndexHelper_->indexAndNames_.size()) {
0128 throw Exception(errors::LogicError)
0129 << "ProductResolverIndexHelper::Matches::Matches - Arguments exceed vector bounds.\n";
0130 }
0131 }
0132
0133 ProductResolverIndex ProductResolverIndexHelper::Matches::index(unsigned int i) const {
0134 if (i >= numberOfMatches_) {
0135 throw Exception(errors::LogicError) << "ProductResolverIndexHelper::Matches::index - Argument is out of range.\n";
0136 }
0137 return productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].index();
0138 }
0139
0140 char const* ProductResolverIndexHelper::Matches::processName(unsigned int i) const {
0141 if (i >= numberOfMatches_) {
0142 throw Exception(errors::LogicError)
0143 << "ProductResolverIndexHelper::Matches::processName - Argument is out of range.\n";
0144 }
0145 unsigned int startInProcessNames =
0146 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInProcessNames();
0147 return &productResolverIndexHelper_->processNames_[startInProcessNames];
0148 }
0149
0150 char const* ProductResolverIndexHelper::Matches::productInstanceName(unsigned int i) const {
0151 if (i >= numberOfMatches_) {
0152 throw Exception(errors::LogicError)
0153 << "ProductResolverIndexHelper::Matches::productInstanceName - Argument is out of range.\n";
0154 }
0155 unsigned int start =
0156 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInBigNamesContainer();
0157 auto moduleLabelSize = strlen(&productResolverIndexHelper_->bigNamesContainer_[start]);
0158 return &productResolverIndexHelper_->bigNamesContainer_[start + moduleLabelSize + 1];
0159 }
0160
0161 char const* ProductResolverIndexHelper::Matches::moduleLabel(unsigned int i) const {
0162 if (i >= numberOfMatches_) {
0163 throw Exception(errors::LogicError)
0164 << "ProductResolverIndexHelper::Matches::moduleLabel - Argument is out of range.\n";
0165 }
0166 unsigned int start =
0167 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInBigNamesContainer();
0168 return &productResolverIndexHelper_->bigNamesContainer_[start];
0169 }
0170
0171 ProductResolverIndexHelper::Matches ProductResolverIndexHelper::relatedIndexes(KindOfType kindOfType,
0172 TypeID const& typeID,
0173 char const* moduleLabel,
0174 char const* instance) const {
0175 unsigned int startInIndexAndNames = indexToIndexAndNames(kindOfType, typeID, moduleLabel, instance, nullptr);
0176 unsigned int numberOfMatches = 1;
0177
0178 if (startInIndexAndNames == std::numeric_limits<unsigned int>::max()) {
0179 numberOfMatches = 0;
0180 } else {
0181 auto vSize = indexAndNames_.size();
0182 for (unsigned int j = startInIndexAndNames + 1U; j < vSize && (indexAndNames_[j].startInProcessNames() != 0U);
0183 ++j) {
0184 ++numberOfMatches;
0185 }
0186 }
0187 return Matches(this, startInIndexAndNames, numberOfMatches);
0188 }
0189
0190 ProductResolverIndexHelper::Matches ProductResolverIndexHelper::relatedIndexes(KindOfType kindOfType,
0191 TypeID const& typeID) const {
0192 unsigned int startInIndexAndNames = std::numeric_limits<unsigned int>::max();
0193 unsigned int numberOfMatches = 0;
0194
0195
0196 unsigned iType = indexToType(kindOfType, typeID);
0197 if (iType != std::numeric_limits<unsigned int>::max()) {
0198
0199 Range const& range = ranges_[iType];
0200
0201 startInIndexAndNames = range.begin();
0202 numberOfMatches = range.end() - range.begin();
0203 }
0204 return Matches(this, startInIndexAndNames, numberOfMatches);
0205 }
0206
0207 ProductResolverIndex ProductResolverIndexHelper::insert(TypeID const& typeID,
0208 char const* moduleLabel,
0209 char const* instance,
0210 char const* process,
0211 TypeID const& containedTypeID,
0212 std::vector<TypeID>* baseTypesOfContainedType) {
0213 if (!items_) {
0214 throw Exception(errors::LogicError)
0215 << "ProductResolverIndexHelper::insert - Attempt to insert more elements after frozen.\n";
0216 }
0217
0218 if (process == nullptr || *process == '\0') {
0219 throw Exception(errors::LogicError) << "ProductResolverIndexHelper::insert - Empty process.\n";
0220 }
0221
0222
0223 Item item(PRODUCT_TYPE, typeID, moduleLabel, instance, process, 0);
0224 std::set<Item>::iterator iter = items_->find(item);
0225 if (iter != items_->end()) {
0226 throw Exception(errors::LogicError)
0227 << "ProductResolverIndexHelper::insert - Attempt to insert duplicate entry.\n";
0228 }
0229
0230
0231 item.setIndex(nextIndexValue_);
0232 unsigned int savedProductIndex = nextIndexValue_;
0233 ++nextIndexValue_;
0234 items_->insert(item);
0235
0236
0237
0238 item.clearProcess();
0239 iter = items_->find(item);
0240 if (iter == items_->end()) {
0241 item.setIndex(nextIndexValue_);
0242 ++nextIndexValue_;
0243 items_->insert(item);
0244 }
0245
0246
0247
0248 if (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID()) {
0249 TypeWithDict containedType(containedTypeID.typeInfo());
0250
0251 Item containedItem(ELEMENT_TYPE, containedTypeID, moduleLabel, instance, process, savedProductIndex);
0252 iter = items_->find(containedItem);
0253 if (iter != items_->end()) {
0254 containedItem.setIndex(ProductResolverIndexAmbiguous);
0255 items_->erase(iter);
0256 }
0257 items_->insert(containedItem);
0258
0259 containedItem.clearProcess();
0260 iter = items_->find(containedItem);
0261 if (iter == items_->end()) {
0262 containedItem.setIndex(nextIndexValue_);
0263 ++nextIndexValue_;
0264 items_->insert(containedItem);
0265 }
0266
0267
0268 if (baseTypesOfContainedType) {
0269 for (TypeID const& baseTypeID : *baseTypesOfContainedType) {
0270 Item baseItem(ELEMENT_TYPE, baseTypeID, moduleLabel, instance, process, savedProductIndex);
0271 iter = items_->find(baseItem);
0272 if (iter != items_->end()) {
0273 baseItem.setIndex(ProductResolverIndexAmbiguous);
0274 items_->erase(iter);
0275 }
0276 items_->insert(baseItem);
0277
0278 baseItem.clearProcess();
0279 iter = items_->find(baseItem);
0280 if (iter == items_->end()) {
0281 baseItem.setIndex(nextIndexValue_);
0282 ++nextIndexValue_;
0283 items_->insert(baseItem);
0284 }
0285 }
0286 }
0287 }
0288 return savedProductIndex;
0289 }
0290
0291 ProductResolverIndex ProductResolverIndexHelper::insert(TypeID const& typeID,
0292 char const* moduleLabel,
0293 char const* instance,
0294 char const* process) {
0295 TypeID containedTypeID = productholderindexhelper::getContainedType(typeID);
0296 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0297 std::vector<TypeID> baseTypes;
0298 std::vector<TypeID>* baseTypesOfContainedType = &baseTypes;
0299 if (hasContainedType) {
0300 std::vector<std::string> missingDictionaries;
0301 public_base_classes(missingDictionaries, containedTypeID, baseTypes);
0302 }
0303 return insert(typeID, moduleLabel, instance, process, containedTypeID, baseTypesOfContainedType);
0304 }
0305
0306 void ProductResolverIndexHelper::setFrozen() {
0307 if (!items_)
0308 return;
0309
0310
0311
0312
0313 bool iFirstThisType = true;
0314 bool beginElementsWasSet = false;
0315 TypeID previousTypeID;
0316 KindOfType previousKindOfType = PRODUCT_TYPE;
0317 std::string previousModuleLabel;
0318 std::string previousInstance;
0319 unsigned int iCountTypes = 0;
0320 unsigned int iCountCharacters = 0;
0321 for (auto const& item : *items_) {
0322 if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
0323 ++iCountTypes;
0324 iFirstThisType = true;
0325
0326 if (!beginElementsWasSet) {
0327 if (item.kindOfType() == ELEMENT_TYPE) {
0328 beginElementsWasSet = true;
0329 } else {
0330 beginElements_ = iCountTypes;
0331 }
0332 }
0333 }
0334
0335 processItems_->insert(item.process());
0336
0337 if (iFirstThisType || item.moduleLabel() != previousModuleLabel || item.instance() != previousInstance) {
0338 iCountCharacters += item.moduleLabel().size();
0339 iCountCharacters += item.instance().size();
0340 iCountCharacters += 2;
0341 }
0342
0343 iFirstThisType = false;
0344 previousTypeID = item.typeID();
0345 previousKindOfType = item.kindOfType();
0346 previousModuleLabel = item.moduleLabel();
0347 previousInstance = item.instance();
0348 }
0349
0350
0351 unsigned int processNamesSize = 0;
0352 for (auto const& processItem : *processItems_) {
0353 processNamesSize += processItem.size();
0354 ++processNamesSize;
0355 }
0356 processNames_.reserve(processNamesSize);
0357 for (auto const& processItem : *processItems_) {
0358 for (auto const& c : processItem) {
0359 processNames_.push_back(c);
0360 }
0361 processNames_.push_back('\0');
0362 lookupProcessNames_.push_back(processItem);
0363 }
0364
0365
0366 sortedTypeIDs_.reserve(iCountTypes);
0367 ranges_.reserve(iCountTypes);
0368 indexAndNames_.reserve(items_->size());
0369 bigNamesContainer_.reserve(iCountCharacters);
0370
0371
0372 bool iFirstType = true;
0373 iFirstThisType = true;
0374 previousTypeID = TypeID();
0375 unsigned int iCount = 0;
0376 unsigned int iBeginning = 0;
0377 iCountCharacters = 0;
0378 unsigned int previousCharacterCount = 0;
0379 if (!items_->empty()) {
0380 for (auto const& item : *items_) {
0381 if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
0382 iFirstThisType = true;
0383 sortedTypeIDs_.push_back(item.typeID());
0384 if (iFirstType) {
0385 iFirstType = false;
0386 } else {
0387 ranges_.push_back(Range(iBeginning, iCount));
0388 }
0389 iBeginning = iCount;
0390 }
0391 ++iCount;
0392
0393 if (iFirstThisType || item.moduleLabel() != previousModuleLabel || item.instance() != previousInstance) {
0394 unsigned int labelSize = item.moduleLabel().size();
0395 for (unsigned int j = 0; j < labelSize; ++j) {
0396 bigNamesContainer_.push_back(item.moduleLabel()[j]);
0397 }
0398 bigNamesContainer_.push_back('\0');
0399
0400 unsigned int instanceSize = item.instance().size();
0401 for (unsigned int j = 0; j < instanceSize; ++j) {
0402 bigNamesContainer_.push_back(item.instance()[j]);
0403 }
0404 bigNamesContainer_.push_back('\0');
0405
0406 previousCharacterCount = iCountCharacters;
0407
0408 iCountCharacters += labelSize;
0409 iCountCharacters += instanceSize;
0410 iCountCharacters += 2;
0411 }
0412
0413 unsigned int processStart = processIndex(item.process().c_str());
0414 if (processStart == std::numeric_limits<unsigned int>::max()) {
0415 throw Exception(errors::LogicError)
0416 << "ProductResolverIndexHelper::setFrozen - Process not found in processNames_.\n";
0417 }
0418 indexAndNames_.emplace_back(item.index(), previousCharacterCount, processStart);
0419
0420 iFirstThisType = false;
0421 previousTypeID = item.typeID();
0422 previousKindOfType = item.kindOfType();
0423 previousModuleLabel = item.moduleLabel();
0424 previousInstance = item.instance();
0425 }
0426 ranges_.push_back(Range(iBeginning, iCount));
0427 }
0428
0429
0430
0431
0432 sanityCheck();
0433
0434
0435
0436 items_ = nullptr;
0437 processItems_ = nullptr;
0438 }
0439
0440 std::vector<std::string> const& ProductResolverIndexHelper::lookupProcessNames() const {
0441 if (items_) {
0442 throw Exception(errors::LogicError)
0443 << "ProductResolverIndexHelper::lookupProcessNames - Attempt to access names before frozen.\n";
0444 }
0445 return lookupProcessNames_;
0446 }
0447
0448 unsigned int ProductResolverIndexHelper::indexToIndexAndNames(KindOfType kindOfType,
0449 TypeID const& typeID,
0450 char const* moduleLabel,
0451 char const* instance,
0452 char const* process) const {
0453
0454 unsigned iType = indexToType(kindOfType, typeID);
0455 if (iType != std::numeric_limits<unsigned int>::max()) {
0456 unsigned startProcess = 0;
0457 if (process) {
0458 startProcess = processIndex(process);
0459 if (startProcess == std::numeric_limits<unsigned int>::max()) {
0460 return std::numeric_limits<unsigned int>::max();
0461 }
0462 }
0463
0464 ProductResolverIndexHelper::Range const& range = ranges_[iType];
0465 unsigned int begin = range.begin();
0466 unsigned int end = range.end();
0467
0468 while (begin < end) {
0469 unsigned int midpoint = begin + ((end - begin) / 2);
0470 char const* namePtr = &bigNamesContainer_[indexAndNames_[midpoint].startInBigNamesContainer()];
0471
0472
0473 char const* label = moduleLabel;
0474 while (*namePtr && (*namePtr == *label)) {
0475 ++namePtr;
0476 ++label;
0477 }
0478 if (*namePtr == *label) {
0479 ++namePtr;
0480
0481
0482 char const* instanceName = instance;
0483 while (*namePtr && (*namePtr == *instanceName)) {
0484 ++namePtr;
0485 ++instanceName;
0486 }
0487 if (*namePtr == *instanceName) {
0488
0489 if (startProcess == indexAndNames_[midpoint].startInProcessNames()) {
0490 return midpoint;
0491 } else {
0492 if (indexAndNames_[midpoint].startInProcessNames() > startProcess) {
0493 while (true) {
0494 --midpoint;
0495 if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
0496 return midpoint;
0497 }
0498 if (indexAndNames_[midpoint].startInProcessNames() == 0)
0499 break;
0500 }
0501 } else {
0502 while (true) {
0503 ++midpoint;
0504 if (midpoint == indexAndNames_.size())
0505 break;
0506 if (indexAndNames_[midpoint].startInProcessNames() == 0)
0507 break;
0508 if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
0509 return midpoint;
0510 }
0511 }
0512 }
0513 break;
0514 }
0515 } else if (*namePtr < *instanceName) {
0516 if (begin == midpoint)
0517 break;
0518 begin = midpoint;
0519 } else {
0520 end = midpoint;
0521 }
0522 } else if (*namePtr < *label) {
0523 if (begin == midpoint)
0524 break;
0525 begin = midpoint;
0526 } else {
0527 end = midpoint;
0528 }
0529 }
0530 }
0531 return std::numeric_limits<unsigned int>::max();
0532 }
0533
0534 unsigned int ProductResolverIndexHelper::indexToType(KindOfType kindOfType, TypeID const& typeID) const {
0535 unsigned int beginType = 0;
0536 unsigned int endType = beginElements_;
0537 if (kindOfType == ELEMENT_TYPE) {
0538 beginType = beginElements_;
0539 endType = sortedTypeIDs_.size();
0540 }
0541
0542 while (beginType < endType) {
0543 unsigned int midpointType = beginType + ((endType - beginType) / 2);
0544 if (sortedTypeIDs_[midpointType] == typeID) {
0545 return midpointType;
0546 } else if (sortedTypeIDs_[midpointType] < typeID) {
0547 if (beginType == midpointType)
0548 break;
0549 beginType = midpointType;
0550 } else {
0551 endType = midpointType;
0552 }
0553 }
0554 return std::numeric_limits<unsigned int>::max();
0555 }
0556
0557 unsigned int ProductResolverIndexHelper::processIndex(char const* process) const {
0558 char const* ptr = &processNames_[0];
0559 char const* begin = ptr;
0560 while (true) {
0561 char const* p = process;
0562 char const* beginName = ptr;
0563 while (*ptr && (*ptr == *p)) {
0564 ++ptr;
0565 ++p;
0566 }
0567 if (*ptr == *p) {
0568 return beginName - begin;
0569 }
0570 while (*ptr) {
0571 ++ptr;
0572 }
0573 ++ptr;
0574 if (static_cast<unsigned>(ptr - begin) >= processNames_.size()) {
0575 return std::numeric_limits<unsigned int>::max();
0576 }
0577 }
0578 return 0;
0579 }
0580
0581 ProductResolverIndexHelper::ModulesToIndiciesMap ProductResolverIndexHelper::indiciesForModulesInProcess(
0582 const std::string& iProcessName) const {
0583 ModulesToIndiciesMap result;
0584 for (unsigned int i = 0; i < beginElements_; ++i) {
0585 auto const& range = ranges_[i];
0586 for (unsigned int j = range.begin(); j < range.end(); ++j) {
0587 auto const& indexAndNames = indexAndNames_[j];
0588 if (0 == strcmp(&processNames_[indexAndNames.startInProcessNames()], iProcessName.c_str())) {
0589
0590 auto pModLabel = &bigNamesContainer_[indexAndNames.startInBigNamesContainer()];
0591 auto l = strlen(pModLabel);
0592 auto pInstance = pModLabel + l + 1;
0593 result.emplace(pModLabel, std::make_tuple(&sortedTypeIDs_[i], pInstance, indexAndNames.index()));
0594 }
0595 }
0596 }
0597 return result;
0598 }
0599
0600 void ProductResolverIndexHelper::sanityCheck() const {
0601 bool sanityChecksPass = true;
0602 if (sortedTypeIDs_.size() != ranges_.size())
0603 sanityChecksPass = false;
0604
0605 unsigned int previousEnd = 0;
0606 for (auto const& range : ranges_) {
0607 if (range.begin() != previousEnd)
0608 sanityChecksPass = false;
0609 if (range.begin() >= range.end())
0610 sanityChecksPass = false;
0611 previousEnd = range.end();
0612 }
0613 if (previousEnd != indexAndNames_.size())
0614 sanityChecksPass = false;
0615
0616 unsigned maxStart = 0;
0617 unsigned maxStartProcess = 0;
0618 for (auto const& indexAndName : indexAndNames_) {
0619 if (indexAndName.index() >= nextIndexValue_ && indexAndName.index() != ProductResolverIndexAmbiguous)
0620 sanityChecksPass = false;
0621
0622 if (indexAndName.startInBigNamesContainer() >= bigNamesContainer_.size())
0623 sanityChecksPass = false;
0624 if (indexAndName.startInProcessNames() >= processNames_.size())
0625 sanityChecksPass = false;
0626
0627 if (indexAndName.startInBigNamesContainer() > maxStart)
0628 maxStart = indexAndName.startInBigNamesContainer();
0629 if (indexAndName.startInProcessNames() > maxStartProcess)
0630 maxStartProcess = indexAndName.startInProcessNames();
0631 }
0632
0633 if (!indexAndNames_.empty()) {
0634 if (bigNamesContainer_.back() != '\0')
0635 sanityChecksPass = false;
0636 if (processNames_.back() != '\0')
0637 sanityChecksPass = false;
0638 if (maxStart >= bigNamesContainer_.size())
0639 sanityChecksPass = false;
0640 unsigned int countZeroes = 0;
0641 for (unsigned j = maxStart; j < bigNamesContainer_.size(); ++j) {
0642 if (bigNamesContainer_[j] == '\0') {
0643 ++countZeroes;
0644 }
0645 }
0646 if (countZeroes != 2)
0647 sanityChecksPass = false;
0648 if (maxStartProcess >= processNames_.size())
0649 sanityChecksPass = false;
0650 countZeroes = 0;
0651 for (unsigned j = maxStartProcess; j < processNames_.size(); ++j) {
0652 if (processNames_[j] == '\0') {
0653 ++countZeroes;
0654 }
0655 }
0656 if (countZeroes != 1)
0657 sanityChecksPass = false;
0658 }
0659
0660 if (!sanityChecksPass) {
0661 throw Exception(errors::LogicError) << "ProductResolverIndexHelper::setFrozen - Detected illegal state.\n";
0662 }
0663 }
0664
0665 ProductResolverIndexHelper::Item::Item(KindOfType kindOfType,
0666 TypeID const& typeID,
0667 std::string const& moduleLabel,
0668 std::string const& instance,
0669 std::string const& process,
0670 ProductResolverIndex index)
0671 : kindOfType_(kindOfType),
0672 typeID_(typeID),
0673 moduleLabel_(moduleLabel),
0674 instance_(instance),
0675 process_(process),
0676 index_(index) {}
0677
0678 bool ProductResolverIndexHelper::Item::operator<(Item const& right) const {
0679 if (kindOfType_ < right.kindOfType_)
0680 return true;
0681 if (kindOfType_ > right.kindOfType_)
0682 return false;
0683 if (typeID_ < right.typeID_)
0684 return true;
0685 if (typeID_ > right.typeID_)
0686 return false;
0687 if (moduleLabel_ < right.moduleLabel_)
0688 return true;
0689 if (moduleLabel_ > right.moduleLabel_)
0690 return false;
0691 if (instance_ < right.instance_)
0692 return true;
0693 if (instance_ > right.instance_)
0694 return false;
0695 return process_ < right.process_;
0696 }
0697
0698 void ProductResolverIndexHelper::print(std::ostream& os) const {
0699 os << "\n******* Dump ProductResolverIndexHelper *************************\n";
0700
0701 os << "\nnextIndexValue_ = " << nextIndexValue_ << "\n";
0702 os << "beginElements_ = " << beginElements_ << "\n";
0703
0704 os << "\n******* sortedTypeIDs_ \n";
0705 for (auto const& i : sortedTypeIDs_) {
0706 os << i << "\n";
0707 }
0708 os << "******* ranges_ \n";
0709 for (auto const& i : ranges_) {
0710 os << i.begin() << " " << i.end() << "\n";
0711 }
0712 os << "******* indexAndNames_ \n";
0713 for (auto const& i : indexAndNames_) {
0714 os << i.index() << " " << i.startInBigNamesContainer() << " ";
0715 char const* ptr = &bigNamesContainer_[i.startInBigNamesContainer()];
0716 while (*ptr) {
0717 os << *ptr;
0718 ++ptr;
0719 }
0720 ++ptr;
0721 os << " ";
0722 while (*ptr) {
0723 os << *ptr;
0724 ++ptr;
0725 }
0726 os << " " << i.startInProcessNames() << " ";
0727 ptr = &processNames_[i.startInProcessNames()];
0728 while (*ptr) {
0729 os << *ptr;
0730 ++ptr;
0731 }
0732 os << "\n";
0733 }
0734 os << "******* bigNamesContainer_ \n";
0735 for (auto i : bigNamesContainer_) {
0736 if (i == '\0')
0737 os << '\\' << '0';
0738 else
0739 os << i;
0740 }
0741 if (!bigNamesContainer_.empty())
0742 os << "\n";
0743 os << "******* processNames_ \n";
0744 for (auto i : processNames_) {
0745 if (i == '\0')
0746 os << '\\' << '0';
0747 else
0748 os << i;
0749 }
0750 if (!processNames_.empty())
0751 os << "\n";
0752 if (items_) {
0753 os << "******* items_ \n";
0754 for (auto const& item : *items_) {
0755 std::cout << item.kindOfType() << " " << item.moduleLabel() << " " << item.instance() << " " << item.process()
0756 << " " << item.index() << " " << item.typeID() << "\n";
0757 }
0758 }
0759 if (processItems_) {
0760 os << "******* processItems_ \n";
0761 for (auto const& item : *processItems_) {
0762 os << item << "\n";
0763 }
0764 }
0765 os << "sortedTypeIDs_.size() = " << sortedTypeIDs_.size() << "\n";
0766 os << "indexAndNames_.size() = " << indexAndNames_.size() << "\n";
0767 os << "bigNamesContainer_.size() = " << bigNamesContainer_.size() << "\n";
0768 os << "processNames_.size() = " << processNames_.size() << "\n";
0769 os << "\n";
0770 }
0771 }