00001
00004 #include "FWCore/Framework/interface/Principal.h"
00005
00006 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00008 #include "FWCore/Framework/interface/DelayedReader.h"
00009 #include "FWCore/Framework/interface/HistoryAppender.h"
00010 #include "FWCore/Framework/interface/ProductDeletedException.h"
00011 #include "FWCore/Utilities/interface/Algorithms.h"
00012 #include "FWCore/Utilities/interface/EDMException.h"
00013 #include "FWCore/Utilities/interface/DictionaryTools.h"
00014 #include "FWCore/Utilities/interface/WrappedClassName.h"
00015
00016 #include <algorithm>
00017 #include <cstring>
00018 #include <limits>
00019 #include <sstream>
00020 #include <stdexcept>
00021 #include <typeinfo>
00022
00023
00024
00025 namespace edm {
00026
00027 ProcessHistory const Principal::emptyProcessHistory_;
00028
00029 static
00030 void
00031 maybeThrowMissingDictionaryException(TypeID const& productType, bool isElement, std::vector<std::string> const& missingDictionaries) {
00032 if(binary_search_all(missingDictionaries, productType.className())) {
00033 checkDictionaries(isElement ? productType.className() : wrappedClassName(productType.className()), false);
00034 throwMissingDictionariesException();
00035 }
00036 }
00037
00038 static
00039 void
00040 throwGroupNotFoundException(char const* where, errors::ErrorCodes error, BranchID const& bid) {
00041 throw Exception(error, "InvalidID")
00042 << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
00043 }
00044
00045 static
00046 void
00047 throwCorruptionException(char const* where, std::string const& branchName) {
00048 throw Exception(errors::EventCorruption)
00049 << "Principal::" << where <<": Product on branch " << branchName << " occurs twice in the same event.\n";
00050 }
00051
00052 static
00053 boost::shared_ptr<cms::Exception>
00054 makeNotFoundException(char const* where, TypeID const& productType, std::string const& label, std::string const& instance, std::string const& process) {
00055 boost::shared_ptr<cms::Exception> exception(new Exception(errors::ProductNotFound));
00056 *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
00057 << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
00058 << (process.empty() ? "" : "Looking for process: ") << process << "\n";
00059 return exception;
00060 }
00061
00062 static
00063 void
00064 throwProductDeletedException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
00065 boost::shared_ptr<cms::Exception> exception(new ProductDeletedException());
00066 *exception << "Principal::" << where << ": The product matching all criteria\nLooking for type: " << productType << "\n"
00067 << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
00068 << (process.empty() ? "" : "Looking for process: ") << process << "\n"
00069 << "Was already deleted. This means there is a configuration error.\nThe module which is asking for this data must be configured to state that it will read this data.";
00070 throw exception;
00071
00072 }
00073
00074
00075 static
00076 void
00077 throwNotFoundException(char const* where, TypeID const& productType, InputTag const& tag) {
00078 boost::shared_ptr<cms::Exception> exception = makeNotFoundException(where, productType, tag.label(), tag.instance(), tag.process());
00079 throw *exception;
00080 }
00081
00082
00083 Principal::Principal(boost::shared_ptr<ProductRegistry const> reg,
00084 ProcessConfiguration const& pc,
00085 BranchType bt,
00086 HistoryAppender* historyAppender) :
00087 EDProductGetter(),
00088 processHistoryPtr_(0),
00089 processHistoryID_(),
00090 processConfiguration_(&pc),
00091 groups_(reg->constProductList().size(), SharedGroupPtr()),
00092 preg_(reg),
00093 reader_(),
00094 productPtrs_(),
00095 branchType_(bt),
00096 historyAppender_(historyAppender) {
00097
00098
00099 std::string const source("source");
00100 ProductRegistry::ProductList const& prodsList = reg->productList();
00101
00102
00103
00104 bool hasAliases = false;
00105 for(auto const& prod : prodsList) {
00106 BranchDescription const& bd = prod.second;
00107 if(bd.branchType() == branchType_) {
00108 if(bd.isAlias()) {
00109 hasAliases = true;
00110 } else {
00111 boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
00112 if(bd.produced()) {
00113 if(bd.moduleLabel() == source) {
00114 addGroupSource(cbd);
00115 } else if(bd.onDemand()) {
00116 assert(branchType_ == InEvent);
00117 addOnDemandGroup(cbd);
00118 } else {
00119 addGroupScheduled(cbd);
00120 }
00121 } else {
00122 addGroupInput(cbd);
00123 }
00124 }
00125 }
00126 }
00127
00128 if(hasAliases) {
00129 for(auto const& prod : prodsList) {
00130 BranchDescription const& bd = prod.second;
00131 if(bd.isAlias() && bd.branchType() == branchType_) {
00132 boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
00133 addGroupAliased(cbd);
00134 }
00135 }
00136 }
00137 }
00138
00139 Principal::~Principal() {
00140 }
00141
00142
00143
00144
00145 size_t
00146 Principal::size() const {
00147 size_t size = 0U;
00148 for(const_iterator it = this->begin(), itEnd = this->end(); it != itEnd; ++it) {
00149 Group const& g = **it;
00150 if(!g.productUnavailable() && !g.onDemand() && !g.branchDescription().dropped()) {
00151 ++size;
00152 }
00153 }
00154 return size;
00155 }
00156
00157
00158 bool
00159 Principal::adjustToNewProductRegistry(ProductRegistry const& reg) {
00160 if(reg.constProductList().size() > groups_.size()) {
00161 return false;
00162 }
00163 ProductRegistry::ProductList const& prodsList = reg.productList();
00164 for(ProductRegistry::ProductList::const_iterator itProdInfo = prodsList.begin(),
00165 itProdInfoEnd = prodsList.end();
00166 itProdInfo != itProdInfoEnd;
00167 ++itProdInfo) {
00168 if(!itProdInfo->second.produced() && (itProdInfo->second.branchType() == branchType_)) {
00169 boost::shared_ptr<ConstBranchDescription> bd(new ConstBranchDescription(itProdInfo->second));
00170 Group *g = getExistingGroup(itProdInfo->second.branchID());
00171 if(g == 0 || g->branchDescription().branchName() != bd->branchName()) {
00172 return false;
00173 }
00174 g->resetBranchDescription(bd);
00175 }
00176 }
00177 return true;
00178 }
00179
00180 void
00181 Principal::addGroupScheduled(boost::shared_ptr<ConstBranchDescription> bd) {
00182 std::auto_ptr<Group> g(new ScheduledGroup(bd));
00183 addGroupOrThrow(g);
00184 }
00185
00186 void
00187 Principal::addGroupSource(boost::shared_ptr<ConstBranchDescription> bd) {
00188 std::auto_ptr<Group> g(new SourceGroup(bd));
00189 addGroupOrThrow(g);
00190 }
00191
00192 void
00193 Principal::addGroupInput(boost::shared_ptr<ConstBranchDescription> bd) {
00194 std::auto_ptr<Group> g(new InputGroup(bd));
00195 addGroupOrThrow(g);
00196 }
00197
00198 void
00199 Principal::addOnDemandGroup(boost::shared_ptr<ConstBranchDescription> bd) {
00200 std::auto_ptr<Group> g(new UnscheduledGroup(bd));
00201 addGroupOrThrow(g);
00202 }
00203
00204 void
00205 Principal::addGroupAliased(boost::shared_ptr<ConstBranchDescription> bd) {
00206 ProductTransientIndex index = preg_->indexFrom(bd->originalBranchID());
00207 assert(index != ProductRegistry::kInvalidIndex);
00208
00209 std::auto_ptr<Group> g(new AliasGroup(bd, dynamic_cast<ProducedGroup&>(*groups_[index])));
00210 addGroupOrThrow(g);
00211 }
00212
00213
00214 void
00215 Principal::clearPrincipal() {
00216 processHistoryPtr_ = 0;
00217 processHistoryID_ = ProcessHistoryID();
00218 reader_ = 0;
00219 for (Principal::const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
00220 (*i)->resetProductData();
00221 }
00222 productPtrs_.clear();
00223 }
00224
00225 void
00226 Principal::deleteProduct(BranchID const& id) {
00227 Group* g = getExistingGroup(id);
00228 assert(0!=g);
00229 auto itFound = productPtrs_.find(g->product().get());
00230 if(itFound != productPtrs_.end()) {
00231 productPtrs_.erase(itFound);
00232 }
00233 g->deleteProduct();
00234 }
00235
00236
00237 void
00238 Principal::fillPrincipal(ProcessHistoryID const& hist, DelayedReader* reader) {
00239 if(reader) {
00240 reader_ = reader;
00241 }
00242
00243 ProcessHistory const* inputProcessHistory = 0;
00244 if (historyAppender_ && productRegistry().anyProductProduced()) {
00245 CachedHistory const& cachedHistory =
00246 historyAppender_->appendToProcessHistory(hist,
00247 *processConfiguration_);
00248 processHistoryPtr_ = cachedHistory.processHistory();
00249 processHistoryID_ = cachedHistory.processHistoryID();
00250 inputProcessHistory = cachedHistory.inputProcessHistory();
00251 }
00252 else {
00253 if (hist.isValid()) {
00254 ProcessHistoryRegistry* registry = ProcessHistoryRegistry::instance();
00255 inputProcessHistory = registry->getMapped(hist);
00256 if (inputProcessHistory == 0) {
00257 throw Exception(errors::LogicError)
00258 << "Principal::fillPrincipal\n"
00259 << "Input ProcessHistory not found in registry\n"
00260 << "Contact a Framework developer\n";
00261 }
00262 } else {
00263 inputProcessHistory = &emptyProcessHistory_;
00264 }
00265 processHistoryID_ = hist;
00266 processHistoryPtr_ = inputProcessHistory;
00267 }
00268
00269 preg_->productLookup().reorderIfNecessary(branchType_, *inputProcessHistory,
00270 processConfiguration_->processName());
00271 preg_->elementLookup().reorderIfNecessary(branchType_, *inputProcessHistory,
00272 processConfiguration_->processName());
00273 }
00274
00275 Group*
00276 Principal::getExistingGroup(BranchID const& branchID) {
00277 ProductTransientIndex index = preg_->indexFrom(branchID);
00278 assert(index != ProductRegistry::kInvalidIndex);
00279 SharedGroupPtr ptr = groups_.at(index);
00280 return ptr.get();
00281 }
00282
00283 Group*
00284 Principal::getExistingGroup(Group const& group) {
00285 Group* g = getExistingGroup(group.branchDescription().branchID());
00286 assert(0 == g || BranchKey(group.branchDescription()) == BranchKey(g->branchDescription()));
00287 return g;
00288 }
00289
00290 void
00291 Principal::addGroup_(std::auto_ptr<Group> group) {
00292 ConstBranchDescription const& bd = group->branchDescription();
00293 assert (!bd.className().empty());
00294 assert (!bd.friendlyClassName().empty());
00295 assert (!bd.moduleLabel().empty());
00296 assert (!bd.processName().empty());
00297 SharedGroupPtr g(group);
00298
00299 ProductTransientIndex index = preg_->indexFrom(bd.branchID());
00300 assert(index != ProductRegistry::kInvalidIndex);
00301 groups_[index] = g;
00302 }
00303
00304 void
00305 Principal::addGroupOrThrow(std::auto_ptr<Group> group) {
00306 Group const* g = getExistingGroup(*group);
00307 if(g != 0) {
00308 ConstBranchDescription const& bd = group->branchDescription();
00309 throw Exception(errors::InsertFailure, "AlreadyPresent")
00310 << "addGroupOrThrow: Problem found while adding product, "
00311 << "product already exists for ("
00312 << bd.friendlyClassName() << ","
00313 << bd.moduleLabel() << ","
00314 << bd.productInstanceName() << ","
00315 << bd.processName()
00316 << ")\n";
00317 }
00318 addGroup_(group);
00319 }
00320
00321 Principal::ConstGroupPtr
00322 Principal::getGroup(BranchID const& bid, bool resolveProd, bool fillOnDemand) const {
00323 ProductTransientIndex index = preg_->indexFrom(bid);
00324 if(index == ProductRegistry::kInvalidIndex){
00325 return ConstGroupPtr();
00326 }
00327 return getGroupByIndex(index, resolveProd, fillOnDemand);
00328 }
00329
00330 Principal::ConstGroupPtr
00331 Principal::getGroupByIndex(ProductTransientIndex const& index, bool resolveProd, bool fillOnDemand) const {
00332
00333 ConstGroupPtr const g = groups_[index].get();
00334 if(0 == g) {
00335 return g;
00336 }
00337 if(resolveProd && !g->productUnavailable()) {
00338 this->resolveProduct(*g, fillOnDemand);
00339 }
00340 return g;
00341 }
00342
00343 BasicHandle
00344 Principal::getByLabel(TypeID const& productType,
00345 std::string const& label,
00346 std::string const& productInstanceName,
00347 std::string const& processName,
00348 size_t& cachedOffset,
00349 int& fillCount) const {
00350
00351 ProductData const* result = findGroupByLabel(productType,
00352 preg_->productLookup(),
00353 label,
00354 productInstanceName,
00355 processName,
00356 cachedOffset,
00357 fillCount);
00358
00359 if(result == 0) {
00360 boost::shared_ptr<cms::Exception> whyFailed = makeNotFoundException("getByLabel", productType, label, productInstanceName, processName);
00361 return BasicHandle(whyFailed);
00362 }
00363 return BasicHandle(*result);
00364 }
00365
00366 void
00367 Principal::getManyByType(TypeID const& productType,
00368 BasicHandleVec& results) const {
00369
00370 findGroups(productType,
00371 preg_->productLookup(),
00372 results);
00373 return;
00374 }
00375
00376 size_t
00377 Principal::getMatchingSequence(TypeID const& typeID,
00378 std::string const& moduleLabel,
00379 std::string const& productInstanceName,
00380 std::string const& processName,
00381 BasicHandle& result) const {
00382
00383 return findGroup(typeID,
00384 preg_->elementLookup(),
00385 moduleLabel,
00386 productInstanceName,
00387 processName,
00388 result);
00389 }
00390
00391 size_t
00392 Principal::findGroups(TypeID const& typeID,
00393 TransientProductLookupMap const& typeLookup,
00394 BasicHandleVec& results) const {
00395 assert(results.empty());
00396
00397 typedef TransientProductLookupMap TypeLookup;
00398
00399
00400
00401 std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const range = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
00402 if(range.first == range.second) {
00403 maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
00404 }
00405
00406 results.reserve(range.second - range.first);
00407
00408 for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
00409
00410 ConstBranchDescription const& bd = *(it->branchDescription());
00411
00412
00413 if(bd.isAlias()) {
00414 continue;
00415 }
00416
00417
00418 ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
00419
00420 if(group && group->productWasDeleted()) {
00421 throwProductDeletedException("findGroups",
00422 typeID,
00423 bd.moduleLabel(),
00424 bd.productInstanceName(),
00425 bd.processName());
00426 }
00427
00428
00429 if(group && !group->productUnavailable()) {
00430
00431 this->resolveProduct(*group, true);
00432
00433
00434 if(group->product() && !group->productUnavailable() && !group->onDemand()) {
00435
00436 BasicHandle bh(group->productData());
00437 results.push_back(bh);
00438 }
00439 }
00440 }
00441 return results.size();
00442 }
00443
00444 size_t
00445 Principal::findGroup(TypeID const& typeID,
00446 TransientProductLookupMap const& typeLookup,
00447 std::string const& moduleLabel,
00448 std::string const& productInstanceName,
00449 std::string const& processName,
00450 BasicHandle& result) const {
00451 assert(!result.isValid());
00452
00453 size_t count = 0U;
00454
00455 typedef TransientProductLookupMap TypeLookup;
00456
00457
00458
00459 std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const range = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
00460 if(range.first == range.second) {
00461 maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
00462 }
00463
00464 unsigned int processLevelFound = std::numeric_limits<unsigned int>::max();
00465 for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
00466 if(it->processIndex() > processLevelFound) {
00467
00468 continue;
00469 }
00470
00471 ConstBranchDescription const& bd = *(it->branchDescription());
00472
00473 if ( moduleLabel == bd.moduleLabel() &&
00474 productInstanceName == bd.productInstanceName() &&
00475 (processName.empty() || processName == bd.processName())) {
00476
00477
00478 ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
00479 if(group && group->productWasDeleted()) {
00480 throwProductDeletedException("findGroup",
00481 typeID,
00482 bd.moduleLabel(),
00483 bd.productInstanceName(),
00484 bd.processName());
00485 }
00486
00487
00488 if(group && !group->productUnavailable()) {
00489
00490 this->resolveProduct(*group, true);
00491
00492
00493 if(group->product() && !group->productUnavailable() && !group->onDemand()) {
00494 if(it->processIndex() < processLevelFound) {
00495 processLevelFound = it->processIndex();
00496 count = 0U;
00497 }
00498 if(count == 0U) {
00499
00500 result = BasicHandle(group->productData());
00501 }
00502 ++count;
00503 }
00504 }
00505 }
00506 }
00507 if(count != 1) result = BasicHandle();
00508 return count;
00509 }
00510
00511 ProductData const*
00512 Principal::findGroupByLabel(TypeID const& typeID,
00513 TransientProductLookupMap const& typeLookup,
00514 std::string const& moduleLabel,
00515 std::string const& productInstanceName,
00516 std::string const& processName,
00517 size_t& cachedOffset,
00518 int& fillCount) const {
00519
00520 typedef TransientProductLookupMap TypeLookup;
00521 bool isCached = (fillCount > 0 && fillCount == typeLookup.fillCount());
00522 bool toBeCached = (fillCount >= 0 && !isCached);
00523
00524 std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> range =
00525 (isCached ? std::make_pair(typeLookup.begin() + cachedOffset, typeLookup.end()) : typeLookup.equal_range(TypeInBranchType(typeID, branchType_), moduleLabel, productInstanceName));
00526
00527 if(toBeCached) {
00528 cachedOffset = range.first - typeLookup.begin();
00529 fillCount = typeLookup.fillCount();
00530 }
00531
00532 if(range.first == range.second) {
00533 if(toBeCached) {
00534 cachedOffset = typeLookup.end() - typeLookup.begin();
00535 }
00536
00537
00538
00539
00540 std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const typeRange = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
00541 if(typeRange.first == typeRange.second) {
00542 maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
00543 }
00544 return 0;
00545 }
00546
00547 if(!processName.empty()) {
00548 if(isCached) {
00549 assert(processName == range.first->branchDescription()->processName());
00550 range.second = range.first + 1;
00551 } else if(toBeCached) {
00552 bool processFound = false;
00553 for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
00554 if(it->isFirst() && it != range.first) {
00555 break;
00556 }
00557 if(processName == it->branchDescription()->processName()) {
00558 processFound = true;
00559 range.first = it;
00560 cachedOffset = range.first - typeLookup.begin();
00561 range.second = range.first + 1;
00562 break;
00563 }
00564 }
00565 if(!processFound) {
00566 cachedOffset = typeLookup.end() - typeLookup.begin();
00567 return 0;
00568 }
00569 }
00570 }
00571
00572 for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
00573 if(it->isFirst() && it != range.first) {
00574 return 0;
00575 }
00576 if(!processName.empty() && processName != it->branchDescription()->processName()) {
00577 continue;
00578 }
00579
00580 ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
00581 if(group && group->productWasDeleted()) {
00582 throwProductDeletedException("findGroupByLabel",
00583 typeID,
00584 moduleLabel,
00585 productInstanceName,
00586 processName);
00587 }
00588
00589
00590 if(group && !group->productUnavailable()) {
00591 this->resolveProduct(*group, true);
00592
00593
00594 if(group->product() && !group->productUnavailable() && !group->onDemand()) {
00595
00596 return &group->productData();
00597 }
00598 }
00599 }
00600 return 0;
00601 }
00602
00603 ProductData const*
00604 Principal::findGroupByTag(TypeID const& typeID, InputTag const& tag) const {
00605 ProductData const* productData =
00606 findGroupByLabel(typeID,
00607 preg_->productLookup(),
00608 tag.label(),
00609 tag.instance(),
00610 tag.process(),
00611 tag.cachedOffset(),
00612 tag.fillCount());
00613 if(productData == 0) {
00614 throwNotFoundException("findProductByTag", typeID, tag);
00615 }
00616 return productData;
00617 }
00618
00619 OutputHandle
00620 Principal::getForOutput(BranchID const& bid, bool getProd) const {
00621 ConstGroupPtr const g = getGroup(bid, getProd, true);
00622 if(g == 0) {
00623 throwGroupNotFoundException("getForOutput", errors::LogicError, bid);
00624 }
00625 if (g->productWasDeleted()) {
00626 throwProductDeletedException("getForOutput",g->productType(),
00627 g->moduleLabel(),
00628 g->productInstanceName(),
00629 g->processName());
00630 }
00631 if(!g->provenance() || (!g->product() && !g->productProvenancePtr())) {
00632 return OutputHandle();
00633 }
00634 return OutputHandle(WrapperHolder(g->product().get(), g->productData().getInterface()), &g->branchDescription(), g->productProvenancePtr());
00635 }
00636
00637 Provenance
00638 Principal::getProvenance(BranchID const& bid) const {
00639 ConstGroupPtr const g = getGroup(bid, false, true);
00640 if(g == 0) {
00641 throwGroupNotFoundException("getProvenance", errors::ProductNotFound, bid);
00642 }
00643
00644 if(g->onDemand()) {
00645 unscheduledFill(g->branchDescription().moduleLabel());
00646 }
00647
00648
00649 if(g->onDemand()) {
00650 throwGroupNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
00651 }
00652
00653 return *g->provenance();
00654 }
00655
00656
00657
00658
00659 void
00660 Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
00661 provenances.clear();
00662 for (auto const& group : *this) {
00663 if(group->provenanceAvailable() && !group->branchDescription().isAlias()) {
00664
00665
00666 if(group->provenance()->product().present()) {
00667 provenances.push_back(group->provenance());
00668 }
00669 }
00670 }
00671 }
00672
00673 void
00674 Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
00675 for (std::vector<BranchID>::const_iterator it = bids.begin(), itEnd = bids.end(); it != itEnd; ++it) {
00676 ProductTransientIndex index= preg_->indexFrom(*it);
00677 assert(index!=ProductRegistry::kInvalidIndex);
00678 ProductTransientIndex indexO = other.preg_->indexFrom(*it);
00679 assert(indexO!=ProductRegistry::kInvalidIndex);
00680 groups_[index].swap(other.groups_[indexO]);
00681 }
00682 reader_->mergeReaders(other.reader());
00683 }
00684
00685 WrapperHolder
00686 Principal::getIt(ProductID const&) const {
00687 assert(0);
00688 return WrapperHolder();
00689 }
00690
00691 void
00692 Principal::maybeFlushCache(TypeID const& tid, InputTag const& tag) const {
00693 if(tag.typeID() != tid ||
00694 tag.branchType() != branchType() ||
00695 tag.productRegistry() != &productRegistry()) {
00696 tag.fillCount() = 0;
00697 tag.cachedOffset() = 0U;
00698 tag.typeID() = tid;
00699 tag.branchType() = branchType();
00700 tag.productRegistry() = &productRegistry();
00701 }
00702 }
00703
00704 void
00705 Principal::checkUniquenessAndType(WrapperOwningHolder const& prod, Group const* g) const {
00706 if(!prod.isValid()) return;
00707
00708
00709 bool alreadyPresent = !productPtrs_.insert(prod.wrapper()).second;
00710 if(alreadyPresent) {
00711 g->checkType(prod);
00712 const_cast<WrapperOwningHolder&>(prod).reset();
00713 throwCorruptionException("checkUniquenessAndType", g->branchDescription().branchName());
00714 }
00715
00716 g->checkType(prod);
00717 }
00718
00719 void
00720 Principal::putOrMerge(WrapperOwningHolder const& prod, Group const* g) const {
00721 bool willBePut = g->putOrMergeProduct();
00722 if(willBePut) {
00723 checkUniquenessAndType(prod, g);
00724 g->putProduct(prod);
00725 } else {
00726 g->checkType(prod);
00727 g->mergeProduct(prod);
00728 }
00729 }
00730
00731 void
00732 Principal::putOrMerge(WrapperOwningHolder const& prod, ProductProvenance& prov, Group* g) {
00733 bool willBePut = g->putOrMergeProduct();
00734 if(willBePut) {
00735 checkUniquenessAndType(prod, g);
00736 g->putProduct(prod, prov);
00737 } else {
00738 g->checkType(prod);
00739 g->mergeProduct(prod, prov);
00740 }
00741 }
00742
00743 void
00744 Principal::adjustIndexesAfterProductRegistryAddition() {
00745 if(preg_->constProductList().size() > groups_.size()) {
00746 GroupCollection newGroups(preg_->constProductList().size(), SharedGroupPtr());
00747 for (Principal::const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
00748 ProductTransientIndex index = preg_->indexFrom((*i)->branchDescription().branchID());
00749 assert(index != ProductRegistry::kInvalidIndex);
00750 newGroups[index] = *i;
00751 }
00752 groups_.swap(newGroups);
00753
00754 ProductRegistry::ProductList const& prodsList = preg_->productList();
00755 for(ProductRegistry::ProductList::const_iterator itProdInfo = prodsList.begin(),
00756 itProdInfoEnd = prodsList.end();
00757 itProdInfo != itProdInfoEnd;
00758 ++itProdInfo) {
00759 if(itProdInfo->second.branchType() == branchType_) {
00760 ProductTransientIndex index = preg_->indexFrom(itProdInfo->second.branchID());
00761 assert(index != ProductRegistry::kInvalidIndex);
00762 if(!groups_[index]) {
00763
00764 assert(!itProdInfo->second.produced());
00765 boost::shared_ptr<ConstBranchDescription> bd(new ConstBranchDescription(itProdInfo->second));
00766 addGroupInput(bd);
00767 }
00768 }
00769 }
00770 }
00771 assert(preg_->constProductList().size() == groups_.size());
00772 }
00773 }