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