File indexing completed on 2022-04-08 00:35: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<TypeWithDict> 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 bool ProductResolverIndexHelper::Matches::isFullyResolved(unsigned int i) const {
0141 if (i >= numberOfMatches_) {
0142 throw Exception(errors::LogicError)
0143 << "ProductResolverIndexHelper::Matches::isFullyResolved - Argument is out of range.\n";
0144 }
0145 return (productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInProcessNames() != 0U);
0146 }
0147
0148 char const* ProductResolverIndexHelper::Matches::processName(unsigned int i) const {
0149 if (i >= numberOfMatches_) {
0150 throw Exception(errors::LogicError)
0151 << "ProductResolverIndexHelper::Matches::processName - Argument is out of range.\n";
0152 }
0153 unsigned int startInProcessNames =
0154 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInProcessNames();
0155 return &productResolverIndexHelper_->processNames_[startInProcessNames];
0156 }
0157
0158 char const* ProductResolverIndexHelper::Matches::productInstanceName(unsigned int i) const {
0159 if (i >= numberOfMatches_) {
0160 throw Exception(errors::LogicError)
0161 << "ProductResolverIndexHelper::Matches::productInstanceName - Argument is out of range.\n";
0162 }
0163 unsigned int start =
0164 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInBigNamesContainer();
0165 auto moduleLabelSize = strlen(&productResolverIndexHelper_->bigNamesContainer_[start]);
0166 return &productResolverIndexHelper_->bigNamesContainer_[start + moduleLabelSize + 1];
0167 }
0168
0169 char const* ProductResolverIndexHelper::Matches::moduleLabel(unsigned int i) const {
0170 if (i >= numberOfMatches_) {
0171 throw Exception(errors::LogicError)
0172 << "ProductResolverIndexHelper::Matches::moduleLabel - Argument is out of range.\n";
0173 }
0174 unsigned int start =
0175 productResolverIndexHelper_->indexAndNames_[startInIndexAndNames_ + i].startInBigNamesContainer();
0176 return &productResolverIndexHelper_->bigNamesContainer_[start];
0177 }
0178
0179 ProductResolverIndexHelper::Matches ProductResolverIndexHelper::relatedIndexes(KindOfType kindOfType,
0180 TypeID const& typeID,
0181 char const* moduleLabel,
0182 char const* instance) const {
0183 unsigned int startInIndexAndNames = indexToIndexAndNames(kindOfType, typeID, moduleLabel, instance, nullptr);
0184 unsigned int numberOfMatches = 1;
0185
0186 if (startInIndexAndNames == std::numeric_limits<unsigned int>::max()) {
0187 numberOfMatches = 0;
0188 } else {
0189 auto vSize = indexAndNames_.size();
0190 for (unsigned int j = startInIndexAndNames + 1U; j < vSize && (indexAndNames_[j].startInProcessNames() != 0U);
0191 ++j) {
0192 ++numberOfMatches;
0193 }
0194 }
0195 return Matches(this, startInIndexAndNames, numberOfMatches);
0196 }
0197
0198 ProductResolverIndexHelper::Matches ProductResolverIndexHelper::relatedIndexes(KindOfType kindOfType,
0199 TypeID const& typeID) const {
0200 unsigned int startInIndexAndNames = std::numeric_limits<unsigned int>::max();
0201 unsigned int numberOfMatches = 0;
0202
0203
0204 unsigned iType = indexToType(kindOfType, typeID);
0205 if (iType != std::numeric_limits<unsigned int>::max()) {
0206
0207 Range const& range = ranges_[iType];
0208
0209 startInIndexAndNames = range.begin();
0210 numberOfMatches = range.end() - range.begin();
0211 }
0212 return Matches(this, startInIndexAndNames, numberOfMatches);
0213 }
0214
0215 ProductResolverIndex ProductResolverIndexHelper::insert(TypeID const& typeID,
0216 char const* moduleLabel,
0217 char const* instance,
0218 char const* process,
0219 TypeID const& containedTypeID,
0220 std::vector<TypeWithDict>* baseTypesOfContainedType) {
0221 if (!items_) {
0222 throw Exception(errors::LogicError)
0223 << "ProductResolverIndexHelper::insert - Attempt to insert more elements after frozen.\n";
0224 }
0225
0226 if (process == nullptr || *process == '\0') {
0227 throw Exception(errors::LogicError) << "ProductResolverIndexHelper::insert - Empty process.\n";
0228 }
0229
0230
0231 Item item(PRODUCT_TYPE, typeID, moduleLabel, instance, process, 0);
0232 std::set<Item>::iterator iter = items_->find(item);
0233 if (iter != items_->end()) {
0234 throw Exception(errors::LogicError)
0235 << "ProductResolverIndexHelper::insert - Attempt to insert duplicate entry.\n";
0236 }
0237
0238
0239 item.setIndex(nextIndexValue_);
0240 unsigned int savedProductIndex = nextIndexValue_;
0241 ++nextIndexValue_;
0242 items_->insert(item);
0243
0244
0245
0246 item.clearProcess();
0247 iter = items_->find(item);
0248 if (iter == items_->end()) {
0249 item.setIndex(nextIndexValue_);
0250 ++nextIndexValue_;
0251 items_->insert(item);
0252 }
0253
0254
0255
0256 if (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID()) {
0257 TypeWithDict containedType(containedTypeID.typeInfo());
0258
0259 Item containedItem(ELEMENT_TYPE, containedTypeID, moduleLabel, instance, process, savedProductIndex);
0260 iter = items_->find(containedItem);
0261 if (iter != items_->end()) {
0262 containedItem.setIndex(ProductResolverIndexAmbiguous);
0263 items_->erase(iter);
0264 }
0265 items_->insert(containedItem);
0266
0267 containedItem.clearProcess();
0268 iter = items_->find(containedItem);
0269 if (iter == items_->end()) {
0270 containedItem.setIndex(nextIndexValue_);
0271 ++nextIndexValue_;
0272 items_->insert(containedItem);
0273 }
0274
0275
0276 if (baseTypesOfContainedType) {
0277 for (TypeWithDict const& baseType : *baseTypesOfContainedType) {
0278 TypeID baseTypeID(baseType.typeInfo());
0279 Item baseItem(ELEMENT_TYPE, baseTypeID, moduleLabel, instance, process, savedProductIndex);
0280 iter = items_->find(baseItem);
0281 if (iter != items_->end()) {
0282 baseItem.setIndex(ProductResolverIndexAmbiguous);
0283 items_->erase(iter);
0284 }
0285 items_->insert(baseItem);
0286
0287 baseItem.clearProcess();
0288 iter = items_->find(baseItem);
0289 if (iter == items_->end()) {
0290 baseItem.setIndex(nextIndexValue_);
0291 ++nextIndexValue_;
0292 items_->insert(baseItem);
0293 }
0294 }
0295 }
0296 }
0297 return savedProductIndex;
0298 }
0299
0300 ProductResolverIndex ProductResolverIndexHelper::insert(TypeID const& typeID,
0301 char const* moduleLabel,
0302 char const* instance,
0303 char const* process) {
0304 TypeID containedTypeID = productholderindexhelper::getContainedType(typeID);
0305 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0306 std::vector<TypeWithDict> baseTypes;
0307 std::vector<TypeWithDict>* baseTypesOfContainedType = &baseTypes;
0308 if (hasContainedType) {
0309 std::vector<std::string> missingDictionaries;
0310 public_base_classes(missingDictionaries, containedTypeID, baseTypes);
0311 }
0312 return insert(typeID, moduleLabel, instance, process, containedTypeID, baseTypesOfContainedType);
0313 }
0314
0315 void ProductResolverIndexHelper::setFrozen() {
0316 if (!items_)
0317 return;
0318
0319
0320
0321
0322 bool iFirstThisType = true;
0323 bool beginElementsWasSet = false;
0324 TypeID previousTypeID;
0325 KindOfType previousKindOfType = PRODUCT_TYPE;
0326 std::string previousModuleLabel;
0327 std::string previousInstance;
0328 unsigned int iCountTypes = 0;
0329 unsigned int iCountCharacters = 0;
0330 for (auto const& item : *items_) {
0331 if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
0332 ++iCountTypes;
0333 iFirstThisType = true;
0334
0335 if (!beginElementsWasSet) {
0336 if (item.kindOfType() == ELEMENT_TYPE) {
0337 beginElementsWasSet = true;
0338 } else {
0339 beginElements_ = iCountTypes;
0340 }
0341 }
0342 }
0343
0344 processItems_->insert(item.process());
0345
0346 if (iFirstThisType || item.moduleLabel() != previousModuleLabel || item.instance() != previousInstance) {
0347 iCountCharacters += item.moduleLabel().size();
0348 iCountCharacters += item.instance().size();
0349 iCountCharacters += 2;
0350 }
0351
0352 iFirstThisType = false;
0353 previousTypeID = item.typeID();
0354 previousKindOfType = item.kindOfType();
0355 previousModuleLabel = item.moduleLabel();
0356 previousInstance = item.instance();
0357 }
0358
0359
0360 unsigned int processNamesSize = 0;
0361 for (auto const& processItem : *processItems_) {
0362 processNamesSize += processItem.size();
0363 ++processNamesSize;
0364 }
0365 processNames_.reserve(processNamesSize);
0366 for (auto const& processItem : *processItems_) {
0367 for (auto const& c : processItem) {
0368 processNames_.push_back(c);
0369 }
0370 processNames_.push_back('\0');
0371 lookupProcessNames_.push_back(processItem);
0372 }
0373
0374
0375 sortedTypeIDs_.reserve(iCountTypes);
0376 ranges_.reserve(iCountTypes);
0377 indexAndNames_.reserve(items_->size());
0378 bigNamesContainer_.reserve(iCountCharacters);
0379
0380
0381 bool iFirstType = true;
0382 iFirstThisType = true;
0383 previousTypeID = TypeID();
0384 unsigned int iCount = 0;
0385 unsigned int iBeginning = 0;
0386 iCountCharacters = 0;
0387 unsigned int previousCharacterCount = 0;
0388 if (!items_->empty()) {
0389 for (auto const& item : *items_) {
0390 if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
0391 iFirstThisType = true;
0392 sortedTypeIDs_.push_back(item.typeID());
0393 if (iFirstType) {
0394 iFirstType = false;
0395 } else {
0396 ranges_.push_back(Range(iBeginning, iCount));
0397 }
0398 iBeginning = iCount;
0399 }
0400 ++iCount;
0401
0402 if (iFirstThisType || item.moduleLabel() != previousModuleLabel || item.instance() != previousInstance) {
0403 unsigned int labelSize = item.moduleLabel().size();
0404 for (unsigned int j = 0; j < labelSize; ++j) {
0405 bigNamesContainer_.push_back(item.moduleLabel()[j]);
0406 }
0407 bigNamesContainer_.push_back('\0');
0408
0409 unsigned int instanceSize = item.instance().size();
0410 for (unsigned int j = 0; j < instanceSize; ++j) {
0411 bigNamesContainer_.push_back(item.instance()[j]);
0412 }
0413 bigNamesContainer_.push_back('\0');
0414
0415 previousCharacterCount = iCountCharacters;
0416
0417 iCountCharacters += labelSize;
0418 iCountCharacters += instanceSize;
0419 iCountCharacters += 2;
0420 }
0421
0422 unsigned int processStart = processIndex(item.process().c_str());
0423 if (processStart == std::numeric_limits<unsigned int>::max()) {
0424 throw Exception(errors::LogicError)
0425 << "ProductResolverIndexHelper::setFrozen - Process not found in processNames_.\n";
0426 }
0427 indexAndNames_.emplace_back(item.index(), previousCharacterCount, processStart);
0428
0429 iFirstThisType = false;
0430 previousTypeID = item.typeID();
0431 previousKindOfType = item.kindOfType();
0432 previousModuleLabel = item.moduleLabel();
0433 previousInstance = item.instance();
0434 }
0435 ranges_.push_back(Range(iBeginning, iCount));
0436 }
0437
0438
0439
0440
0441 sanityCheck();
0442
0443
0444
0445 items_ = nullptr;
0446 processItems_ = nullptr;
0447 }
0448
0449 std::vector<std::string> const& ProductResolverIndexHelper::lookupProcessNames() const {
0450 if (items_) {
0451 throw Exception(errors::LogicError)
0452 << "ProductResolverIndexHelper::lookupProcessNames - Attempt to access names before frozen.\n";
0453 }
0454 return lookupProcessNames_;
0455 }
0456
0457 unsigned int ProductResolverIndexHelper::indexToIndexAndNames(KindOfType kindOfType,
0458 TypeID const& typeID,
0459 char const* moduleLabel,
0460 char const* instance,
0461 char const* process) const {
0462
0463 unsigned iType = indexToType(kindOfType, typeID);
0464 if (iType != std::numeric_limits<unsigned int>::max()) {
0465 unsigned startProcess = 0;
0466 if (process) {
0467 startProcess = processIndex(process);
0468 if (startProcess == std::numeric_limits<unsigned int>::max()) {
0469 return std::numeric_limits<unsigned int>::max();
0470 }
0471 }
0472
0473 ProductResolverIndexHelper::Range const& range = ranges_[iType];
0474 unsigned int begin = range.begin();
0475 unsigned int end = range.end();
0476
0477 while (begin < end) {
0478 unsigned int midpoint = begin + ((end - begin) / 2);
0479 char const* namePtr = &bigNamesContainer_[indexAndNames_[midpoint].startInBigNamesContainer()];
0480
0481
0482 char const* label = moduleLabel;
0483 while (*namePtr && (*namePtr == *label)) {
0484 ++namePtr;
0485 ++label;
0486 }
0487 if (*namePtr == *label) {
0488 ++namePtr;
0489
0490
0491 char const* instanceName = instance;
0492 while (*namePtr && (*namePtr == *instanceName)) {
0493 ++namePtr;
0494 ++instanceName;
0495 }
0496 if (*namePtr == *instanceName) {
0497
0498 if (startProcess == indexAndNames_[midpoint].startInProcessNames()) {
0499 return midpoint;
0500 } else {
0501 if (indexAndNames_[midpoint].startInProcessNames() > startProcess) {
0502 while (true) {
0503 --midpoint;
0504 if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
0505 return midpoint;
0506 }
0507 if (indexAndNames_[midpoint].startInProcessNames() == 0)
0508 break;
0509 }
0510 } else {
0511 while (true) {
0512 ++midpoint;
0513 if (midpoint == indexAndNames_.size())
0514 break;
0515 if (indexAndNames_[midpoint].startInProcessNames() == 0)
0516 break;
0517 if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
0518 return midpoint;
0519 }
0520 }
0521 }
0522 break;
0523 }
0524 } else if (*namePtr < *instanceName) {
0525 if (begin == midpoint)
0526 break;
0527 begin = midpoint;
0528 } else {
0529 end = midpoint;
0530 }
0531 } else if (*namePtr < *label) {
0532 if (begin == midpoint)
0533 break;
0534 begin = midpoint;
0535 } else {
0536 end = midpoint;
0537 }
0538 }
0539 }
0540 return std::numeric_limits<unsigned int>::max();
0541 }
0542
0543 unsigned int ProductResolverIndexHelper::indexToType(KindOfType kindOfType, TypeID const& typeID) const {
0544 unsigned int beginType = 0;
0545 unsigned int endType = beginElements_;
0546 if (kindOfType == ELEMENT_TYPE) {
0547 beginType = beginElements_;
0548 endType = sortedTypeIDs_.size();
0549 }
0550
0551 while (beginType < endType) {
0552 unsigned int midpointType = beginType + ((endType - beginType) / 2);
0553 if (sortedTypeIDs_[midpointType] == typeID) {
0554 return midpointType;
0555 } else if (sortedTypeIDs_[midpointType] < typeID) {
0556 if (beginType == midpointType)
0557 break;
0558 beginType = midpointType;
0559 } else {
0560 endType = midpointType;
0561 }
0562 }
0563 return std::numeric_limits<unsigned int>::max();
0564 }
0565
0566 unsigned int ProductResolverIndexHelper::processIndex(char const* process) const {
0567 char const* ptr = &processNames_[0];
0568 char const* begin = ptr;
0569 while (true) {
0570 char const* p = process;
0571 char const* beginName = ptr;
0572 while (*ptr && (*ptr == *p)) {
0573 ++ptr;
0574 ++p;
0575 }
0576 if (*ptr == *p) {
0577 return beginName - begin;
0578 }
0579 while (*ptr) {
0580 ++ptr;
0581 }
0582 ++ptr;
0583 if (static_cast<unsigned>(ptr - begin) >= processNames_.size()) {
0584 return std::numeric_limits<unsigned int>::max();
0585 }
0586 }
0587 return 0;
0588 }
0589
0590 ProductResolverIndexHelper::ModulesToIndiciesMap ProductResolverIndexHelper::indiciesForModulesInProcess(
0591 const std::string& iProcessName) const {
0592 ModulesToIndiciesMap result;
0593 for (unsigned int i = 0; i < beginElements_; ++i) {
0594 auto const& range = ranges_[i];
0595 for (unsigned int j = range.begin(); j < range.end(); ++j) {
0596 auto const& indexAndNames = indexAndNames_[j];
0597 if (0 == strcmp(&processNames_[indexAndNames.startInProcessNames()], iProcessName.c_str())) {
0598
0599 auto pModLabel = &bigNamesContainer_[indexAndNames.startInBigNamesContainer()];
0600 auto l = strlen(pModLabel);
0601 auto pInstance = pModLabel + l + 1;
0602 result.emplace(pModLabel, std::make_tuple(&sortedTypeIDs_[i], pInstance, indexAndNames.index()));
0603 }
0604 }
0605 }
0606 return result;
0607 }
0608
0609 void ProductResolverIndexHelper::sanityCheck() const {
0610 bool sanityChecksPass = true;
0611 if (sortedTypeIDs_.size() != ranges_.size())
0612 sanityChecksPass = false;
0613
0614 unsigned int previousEnd = 0;
0615 for (auto const& range : ranges_) {
0616 if (range.begin() != previousEnd)
0617 sanityChecksPass = false;
0618 if (range.begin() >= range.end())
0619 sanityChecksPass = false;
0620 previousEnd = range.end();
0621 }
0622 if (previousEnd != indexAndNames_.size())
0623 sanityChecksPass = false;
0624
0625 unsigned maxStart = 0;
0626 unsigned maxStartProcess = 0;
0627 for (auto const& indexAndName : indexAndNames_) {
0628 if (indexAndName.index() >= nextIndexValue_ && indexAndName.index() != ProductResolverIndexAmbiguous)
0629 sanityChecksPass = false;
0630
0631 if (indexAndName.startInBigNamesContainer() >= bigNamesContainer_.size())
0632 sanityChecksPass = false;
0633 if (indexAndName.startInProcessNames() >= processNames_.size())
0634 sanityChecksPass = false;
0635
0636 if (indexAndName.startInBigNamesContainer() > maxStart)
0637 maxStart = indexAndName.startInBigNamesContainer();
0638 if (indexAndName.startInProcessNames() > maxStartProcess)
0639 maxStartProcess = indexAndName.startInProcessNames();
0640 }
0641
0642 if (!indexAndNames_.empty()) {
0643 if (bigNamesContainer_.back() != '\0')
0644 sanityChecksPass = false;
0645 if (processNames_.back() != '\0')
0646 sanityChecksPass = false;
0647 if (maxStart >= bigNamesContainer_.size())
0648 sanityChecksPass = false;
0649 unsigned int countZeroes = 0;
0650 for (unsigned j = maxStart; j < bigNamesContainer_.size(); ++j) {
0651 if (bigNamesContainer_[j] == '\0') {
0652 ++countZeroes;
0653 }
0654 }
0655 if (countZeroes != 2)
0656 sanityChecksPass = false;
0657 if (maxStartProcess >= processNames_.size())
0658 sanityChecksPass = false;
0659 countZeroes = 0;
0660 for (unsigned j = maxStartProcess; j < processNames_.size(); ++j) {
0661 if (processNames_[j] == '\0') {
0662 ++countZeroes;
0663 }
0664 }
0665 if (countZeroes != 1)
0666 sanityChecksPass = false;
0667 }
0668
0669 if (!sanityChecksPass) {
0670 throw Exception(errors::LogicError) << "ProductResolverIndexHelper::setFrozen - Detected illegal state.\n";
0671 }
0672 }
0673
0674 ProductResolverIndexHelper::Item::Item(KindOfType kindOfType,
0675 TypeID const& typeID,
0676 std::string const& moduleLabel,
0677 std::string const& instance,
0678 std::string const& process,
0679 ProductResolverIndex index)
0680 : kindOfType_(kindOfType),
0681 typeID_(typeID),
0682 moduleLabel_(moduleLabel),
0683 instance_(instance),
0684 process_(process),
0685 index_(index) {}
0686
0687 bool ProductResolverIndexHelper::Item::operator<(Item const& right) const {
0688 if (kindOfType_ < right.kindOfType_)
0689 return true;
0690 if (kindOfType_ > right.kindOfType_)
0691 return false;
0692 if (typeID_ < right.typeID_)
0693 return true;
0694 if (typeID_ > right.typeID_)
0695 return false;
0696 if (moduleLabel_ < right.moduleLabel_)
0697 return true;
0698 if (moduleLabel_ > right.moduleLabel_)
0699 return false;
0700 if (instance_ < right.instance_)
0701 return true;
0702 if (instance_ > right.instance_)
0703 return false;
0704 return process_ < right.process_;
0705 }
0706
0707 void ProductResolverIndexHelper::print(std::ostream& os) const {
0708 os << "\n******* Dump ProductResolverIndexHelper *************************\n";
0709
0710 os << "\nnextIndexValue_ = " << nextIndexValue_ << "\n";
0711 os << "beginElements_ = " << beginElements_ << "\n";
0712
0713 os << "\n******* sortedTypeIDs_ \n";
0714 for (auto const& i : sortedTypeIDs_) {
0715 os << i << "\n";
0716 }
0717 os << "******* ranges_ \n";
0718 for (auto const& i : ranges_) {
0719 os << i.begin() << " " << i.end() << "\n";
0720 }
0721 os << "******* indexAndNames_ \n";
0722 for (auto const& i : indexAndNames_) {
0723 os << i.index() << " " << i.startInBigNamesContainer() << " ";
0724 char const* ptr = &bigNamesContainer_[i.startInBigNamesContainer()];
0725 while (*ptr) {
0726 os << *ptr;
0727 ++ptr;
0728 }
0729 ++ptr;
0730 os << " ";
0731 while (*ptr) {
0732 os << *ptr;
0733 ++ptr;
0734 }
0735 os << " " << i.startInProcessNames() << " ";
0736 ptr = &processNames_[i.startInProcessNames()];
0737 while (*ptr) {
0738 os << *ptr;
0739 ++ptr;
0740 }
0741 os << "\n";
0742 }
0743 os << "******* bigNamesContainer_ \n";
0744 for (auto i : bigNamesContainer_) {
0745 if (i == '\0')
0746 os << '\\' << '0';
0747 else
0748 os << i;
0749 }
0750 if (!bigNamesContainer_.empty())
0751 os << "\n";
0752 os << "******* processNames_ \n";
0753 for (auto i : processNames_) {
0754 if (i == '\0')
0755 os << '\\' << '0';
0756 else
0757 os << i;
0758 }
0759 if (!processNames_.empty())
0760 os << "\n";
0761 if (items_) {
0762 os << "******* items_ \n";
0763 for (auto const& item : *items_) {
0764 std::cout << item.kindOfType() << " " << item.moduleLabel() << " " << item.instance() << " " << item.process()
0765 << " " << item.index() << " " << item.typeID() << "\n";
0766 }
0767 }
0768 if (processItems_) {
0769 os << "******* processItems_ \n";
0770 for (auto const& item : *processItems_) {
0771 os << item << "\n";
0772 }
0773 }
0774 os << "sortedTypeIDs_.size() = " << sortedTypeIDs_.size() << "\n";
0775 os << "indexAndNames_.size() = " << indexAndNames_.size() << "\n";
0776 os << "bigNamesContainer_.size() = " << bigNamesContainer_.size() << "\n";
0777 os << "processNames_.size() = " << processNames_.size() << "\n";
0778 os << "\n";
0779 }
0780 }