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