CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ProductRegistry.cc
Go to the documentation of this file.
1 
12 
17 
18 #include <algorithm>
19 #include <limits>
20 #include <sstream>
21 
22 namespace edm {
23  namespace {
24  void checkDicts(BranchDescription const& productDesc) {
25  if(productDesc.transient()) {
26  checkDictionaries(productDesc.fullClassName(), true);
27  checkDictionaries(wrappedClassName(productDesc.fullClassName()), true);
28  } else {
29  checkDictionaries(wrappedClassName(productDesc.fullClassName()), false);
30  }
31  }
32  }
33 
35  productList_(),
36  transient_() {
37  }
38 
40  frozen_(false),
41  constProductList_(),
42  productProduced_(),
43  anyProductProduced_(false),
44  productLookup_(),
45  elementLookup_(),
46  branchIDToIndex_(),
47  producedBranchListIndex_(std::numeric_limits<BranchListIndex>::max()),
48  missingDictionaries_() {
49  for(size_t i = 0; i < productProduced_.size(); ++i) productProduced_[i] = false;
50  }
51 
52  void
54  frozen_ = false;
55  constProductList_.clear();
56  for (size_t i = 0; i < productProduced_.size(); ++i) productProduced_[i] = false;
57  anyProductProduced_ = false;
58  productLookup_.reset();
59  elementLookup_.reset();
60  branchIDToIndex_.clear();
61  producedBranchListIndex_ = std::numeric_limits<BranchListIndex>::max();
62  missingDictionaries_.clear();
63  }
64 
66  productList_(productList),
67  transient_() {
68  frozen() = toBeFrozen;
69  }
70 
71  void
73  bool fromListener) {
74  assert(productDesc.produced());
75  throwIfFrozen();
76  checkDicts(productDesc);
77  std::pair<ProductList::iterator, bool> ret =
78  productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
79  if(!ret.second) {
80  throw Exception(errors::Configuration, "Duplicate Process")
81  << "The process name " << productDesc.processName() << " was previously used on these products.\n"
82  << "Please modify the configuration file to use a distinct process name.\n";
83  }
84  addCalled(productDesc, fromListener);
85  }
86 
87  void
89  assert(!productDesc.produced());
90  throwIfFrozen();
91  productDesc.init();
92  BranchKey k = BranchKey(productDesc);
93  ProductList::iterator iter = productList_.find(k);
94  if(iter == productList_.end()) {
95  productList_.insert(std::make_pair(k, productDesc));
96  } else {
97  assert(combinable(iter->second, productDesc));
98  iter->second.merge(productDesc);
99  }
100  }
101 
102  bool
105  for(ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end();
106  it != itEnd; ++it) {
107  if(it->second.branchType() == brType) {
108  return true;
109  }
110  }
111  return false;
112  }
113 
114  void
115  ProductRegistry::setFrozen(bool initializeLookupInfo) const {
116  if(frozen()) return;
117  frozen() = true;
118  if(initializeLookupInfo) {
120  }
121  }
122 
123  void
125  if(frozen()) {
126  throw cms::Exception("ProductRegistry", "throwIfFrozen")
127  << "cannot modify the ProductRegistry because it is frozen\n";
128  }
129  }
130 
131  void
133  if(!frozen()) {
134  throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
135  << "cannot read the ProductRegistry because it is not yet frozen\n";
136  }
137  }
138 
139  void
141  }
142 
143  std::vector<std::string>
145  std::vector<std::string> result;
146  result.reserve(productList().size());
147 
148  ProductList::const_iterator it = productList().begin();
149  ProductList::const_iterator end = productList().end();
150 
151  for(; it != end; ++it) result.push_back(it->second.branchName());
152 
153  return result;
154  }
155 
156  std::vector<BranchDescription const*>
158  std::vector<BranchDescription const*> result;
159  result.reserve(productList().size());
160 
161  ProductList::const_iterator it = productList().begin();
162  ProductList::const_iterator end = productList().end();
163 
164  for(; it != end; ++it) result.push_back(&(it->second));
165  return result;
166  }
167 
168  void
170  for(ProductList::const_iterator it = other.begin(), itEnd = other.end();
171  it != itEnd; ++it) {
172  copyProduct(it->second);
173  }
174  }
175 
176  void
177  ProductRegistry::updateFromInput(std::vector<BranchDescription> const& other) {
178  for(std::vector<BranchDescription>::const_iterator it = other.begin(), itEnd = other.end();
179  it != itEnd; ++it) {
180  copyProduct(*it);
181  }
182  }
183 
184  std::string
186  std::string const& fileName,
187  BranchDescription::MatchMode parametersMustMatch,
188  BranchDescription::MatchMode branchesMustMatch) {
189  std::ostringstream differences;
190 
191  ProductRegistry::ProductList::iterator j = productList_.begin();
192  ProductRegistry::ProductList::iterator s = productList_.end();
193  ProductRegistry::ProductList::const_iterator i = other.productList().begin();
194  ProductRegistry::ProductList::const_iterator e = other.productList().end();
195 
196  // Loop over entries in the main product registry.
197  while(j != s || i != e) {
198  if(j != s && j->second.produced()) {
199  // Ignore branches just produced (i.e. not in input file).
200  ++j;
201  } else if(j == s || (i != e && i->first < j->first)) {
202  if(i->second.present()) {
203  differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
204  differences << " but not in previous files.\n";
205  } else {
206  productList_.insert(*i);
207  }
208  ++i;
209  } else if(i == e || (j != s && j->first < i->first)) {
210  if(j->second.present() && branchesMustMatch == BranchDescription::Strict) {
211  differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
212  differences << " but not in file '" << fileName << "'.\n";
213  }
214  ++j;
215  } else {
216  std::string difs = match(j->second, i->second, fileName, parametersMustMatch);
217  if(difs.empty()) {
218  if(parametersMustMatch == BranchDescription::Permissive) j->second.merge(i->second);
219  } else {
220  differences << difs;
221  }
222  ++i;
223  ++j;
224  }
225  }
227  return differences.str();
228  }
229 
230  static void
233  ConstBranchDescription const* branchDesc,
235  oMap[std::make_pair(TypeInBranchType(TypeID(type.TypeInfo()),
236  branchDesc->branchType()),
237  branchDesc)] = index;
238  }
239 
241  StringSet savedMissingTypes;
242  savedMissingTypes.swap(missingTypes());
243  StringSet savedFoundTypes;
244  savedFoundTypes.swap(foundTypes());
245  constProductList().clear();
248 
249  //NOTE it might be possible to remove the need for this temporary map because the productList is ordered by the
250  // BranchKey and for the same C++ class type the BranchKey will sort just like CompareTypeInBranchTypeConstBranchDescription
251  typedef TransientProductLookupMap::FillFromMap TempLookupMap;
252  TempLookupMap tempProductLookupMap;
253  TempLookupMap tempElementLookupMap;
254 
255  StringSet usedProcessNames;
256  StringSet missingDicts;
257  for(ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i, ++index) {
258  if(i->second.produced()) {
259  setProductProduced(i->second.branchType());
260  }
261 
262  //insert returns a pair<iterator, bool> and we want the address of the ConstBranchDescription that was created in the map
263  // this is safe since items in a map always retain their memory address
264  ConstBranchDescription const* pBD = &(constProductList().insert(std::make_pair(i->first, ConstBranchDescription(i->second))).first->second);
265 
266  transient_.branchIDToIndex_[i->second.branchID()] = index;
267 
268  usedProcessNames.insert(pBD->processName());
269 
270  //only do the following if the data is supposed to be available in the event
271  if(i->second.present()) {
272  Reflex::Type type(Reflex::Type::ByName(i->second.className()));
273  Reflex::Type wrappedType(Reflex::Type::ByName(wrappedClassName(i->second.className())));
274  if(!bool(type) || !bool(wrappedType)) {
275  missingDicts.insert(i->second.className());
276  continue;
277  }
278  fillLookup(type, index, pBD, tempProductLookupMap);
279 
280  if(bool(type)) {
281  // Here we look in the object named "type" for a typedef
282  // named "value_type" and get the Reflex::Type for it.
283  // Then check to ensure the Reflex dictionary is defined
284  // for this value_type.
285  // I do not throw an exception here if the check fails
286  // because there are known cases where the dictionary does
287  // not exist and we do not need to support those cases.
288  Reflex::Type valueType;
289  if((is_RefVector(type, valueType) ||
290  is_PtrVector(type, valueType) ||
291  is_RefToBaseVector(type, valueType) ||
292  value_type_of(type, valueType))
293  && bool(valueType)) {
294 
295  fillLookup(valueType, index, pBD, tempElementLookupMap);
296 
297  // Repeat this for all public base classes of the value_type
298  std::vector<Reflex::Type> baseTypes;
299  public_base_classes(valueType, baseTypes);
300 
301  for(std::vector<Reflex::Type>::iterator iter = baseTypes.begin(),
302  iend = baseTypes.end();
303  iter != iend;
304  ++iter) {
305  fillLookup(*iter, index, pBD, tempElementLookupMap);
306  }
307  }
308  }
309  }
310  }
311  missingDictionaries().reserve(missingDicts.size());
312  copy_all(missingDicts, std::back_inserter(missingDictionaries()));
313  productLookup().fillFrom(tempProductLookupMap);
314  elementLookup().fillFrom(tempElementLookupMap);
315  savedMissingTypes.swap(missingTypes());
316  savedFoundTypes.swap(foundTypes());
317  }
318 
320  std::map<BranchID, ProductTransientIndex>::iterator itFind = transient_.branchIDToIndex_.find(iID);
321  if(itFind == transient_.branchIDToIndex_.end()) {
322  return kInvalidIndex;
323  }
324  return itFind->second;
325  }
326 
327  void ProductRegistry::print(std::ostream& os) const {
328  for(ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i) {
329  os << i->second << "\n-----\n";
330  }
331  }
332 }
std::string const & processName() const
type
Definition: HCALResponse.h:22
int i
Definition: DBlmapReader.cc:9
unsigned short BranchListIndex
bool is_RefToBaseVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:86
void setProductProduced(BranchType branchType) const
ConstProductList & constProductList() const
void throwIfNotFrozen() const
std::vector< std::string > allBranchNames() const
bool is_PtrVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:69
bool value_type_of(Reflex::Type const &t, Reflex::Type &found_type)
Definition: ReflexTools.h:31
std::map< BranchKey, BranchDescription > ProductList
bool & produced() const
static ProductTransientIndex const kInvalidIndex
bool anyProducts(BranchType const brType) const
std::string const & processName() const
std::string merge(ProductRegistry const &other, std::string const &fileName, BranchDescription::MatchMode parametersMustMatch=BranchDescription::Permissive, BranchDescription::MatchMode branchesMustMatch=BranchDescription::Permissive)
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName, BranchDescription::MatchMode m)
void public_base_classes(Reflex::Type const &type, std::vector< Reflex::Type > &baseTypes)
ProductList::size_type size() const
BranchType
Definition: BranchType.h:11
virtual void addCalled(BranchDescription const &, bool iFromListener)
ProductList const & productList() const
TransientProductLookupMap & elementLookup() const
const T & max(const T &a, const T &b)
std::vector< std::string > & missingDictionaries() const
bool combinable(BranchDescription const &a, BranchDescription const &b)
StringSet & missingTypes()
Definition: ReflexTools.cc:189
std::set< std::string > StringSet
Definition: ReflexTools.h:22
tuple result
Definition: query.py:137
void checkDictionaries(std::string const &name, bool noComponents=false)
Definition: ReflexTools.cc:199
int j
Definition: DBlmapReader.cc:9
std::vector< BranchDescription const * > allBranchDescriptions() const
boost::array< bool, NumBranchTypes > productProduced_
#define end
Definition: vmac.h:38
StringSet & foundTypes()
Definition: ReflexTools.cc:193
void print(std::ostream &os) const
static void fillLookup(Reflex::Type const &type, ProductTransientIndex const &index, ConstBranchDescription const *branchDesc, TransientProductLookupMap::FillFromMap &oMap)
int k[5][pyjets_maxn]
void setFrozen(bool initializeLookupInfo=true) const
void initializeLookupTables() const
TransientProductLookupMap & productLookup() const
std::string wrappedClassName(std::string const &iFullName)
BranchType const & branchType() const
bool is_RefVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:56
author Stefano ARGIRO author Bill Tanenbaum
Func copy_all(ForwardSequence &s, Func f)
wrappers for copy
Definition: Algorithms.h:24
void throwIfFrozen() const
void updateFromInput(ProductList const &other)
bool & frozen() const
ProductTransientIndex indexFrom(BranchID const &iID) const
std::map< std::pair< TypeInBranchType, ConstBranchDescription const * >, ProductTransientIndex, CompareTypeInBranchTypeConstBranchDescription > FillFromMap
void addProduct(BranchDescription const &productdesc, bool iFromListener=false)
std::map< BranchID, ProductTransientIndex > branchIDToIndex_
void copyProduct(BranchDescription const &productdesc)
EventID const & max(EventID const &lh, EventID const &rh)
Definition: EventID.h:137