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  } else {
28  checkDictionaries(wrappedClassName(productDesc.fullClassName()), false);
29  }
30  }
31  }
32 
34  productList_(),
35  transients_() {
36  }
37 
39  frozen_(false),
40  constProductList_(),
41  productProduced_(),
42  anyProductProduced_(false),
43  productLookup_(),
44  elementLookup_(),
45  branchIDToIndex_(),
46  producedBranchListIndex_(std::numeric_limits<BranchListIndex>::max()) {
47  for(size_t i = 0; i < productProduced_.size(); ++i) productProduced_[i] = false;
48  }
49 
51  productList_(productList),
52  transients_() {
53  frozen() = toBeFrozen;
54  }
55 
56  void
58  bool fromListener) {
59  assert(productDesc.produced());
60  throwIfFrozen();
61  checkDicts(productDesc);
62  std::pair<ProductList::iterator, bool> ret =
63  productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
64  if(!ret.second) {
65  throw Exception(errors::Configuration, "Duplicate Process")
66  << "The process name " << productDesc.processName() << " was previously used on these products.\n"
67  << "Please modify the configuration file to use a distinct process name.\n";
68  }
69  addCalled(productDesc, fromListener);
70  }
71 
72  void
74  assert(!productDesc.produced());
75  throwIfFrozen();
76  productDesc.init();
77  BranchKey k = BranchKey(productDesc);
78  ProductList::iterator iter = productList_.find(k);
79  if(iter == productList_.end()) {
80  productList_.insert(std::make_pair(k, productDesc));
81  } else {
82  assert(combinable(iter->second, productDesc));
83  iter->second.merge(productDesc);
84  }
85  }
86 
87  bool
90  for(ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end();
91  it != itEnd; ++it) {
92  if(it->second.branchType() == brType) {
93  return true;
94  }
95  }
96  return false;
97  }
98 
99  void
100  ProductRegistry::setFrozen(bool initializeLookupInfo) const {
101  if(frozen()) return;
102  frozen() = true;
103  if(initializeLookupInfo) {
105  }
106  }
107 
108  void
110  if(frozen()) {
111  throw cms::Exception("ProductRegistry", "throwIfFrozen")
112  << "cannot modify the ProductRegistry because it is frozen\n";
113  }
114  }
115 
116  void
118  if(!frozen()) {
119  throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
120  << "cannot read the ProductRegistry because it is not yet frozen\n";
121  }
122  }
123 
124  void
126  }
127 
128  std::vector<std::string>
130  std::vector<std::string> result;
131  result.reserve(productList().size());
132 
133  ProductList::const_iterator it = productList().begin();
134  ProductList::const_iterator end = productList().end();
135 
136  for(; it != end; ++it) result.push_back(it->second.branchName());
137 
138  return result;
139  }
140 
141  std::vector<BranchDescription const*>
143  std::vector<BranchDescription const*> result;
144  result.reserve(productList().size());
145 
146  ProductList::const_iterator it = productList().begin();
147  ProductList::const_iterator end = productList().end();
148 
149  for(; it != end; ++it) result.push_back(&(it->second));
150  return result;
151  }
152 
153  void
155  for(ProductList::const_iterator it = other.begin(), itEnd = other.end();
156  it != itEnd; ++it) {
157  copyProduct(it->second);
158  }
159  }
160 
161  void
162  ProductRegistry::updateFromInput(std::vector<BranchDescription> const& other) {
163  for(std::vector<BranchDescription>::const_iterator it = other.begin(), itEnd = other.end();
164  it != itEnd; ++it) {
165  copyProduct(*it);
166  }
167  }
168 
169  std::string
171  std::string const& fileName,
172  BranchDescription::MatchMode parametersMustMatch,
173  BranchDescription::MatchMode branchesMustMatch) {
174  std::ostringstream differences;
175 
176  ProductRegistry::ProductList::iterator j = productList_.begin();
177  ProductRegistry::ProductList::iterator s = productList_.end();
178  ProductRegistry::ProductList::const_iterator i = other.productList().begin();
179  ProductRegistry::ProductList::const_iterator e = other.productList().end();
180 
181  // Loop over entries in the main product registry.
182  while(j != s || i != e) {
183  if(j != s && j->second.produced()) {
184  // Ignore branches just produced (i.e. not in input file).
185  ++j;
186  } else if(j == s || (i != e && i->first < j->first)) {
187  if(i->second.present()) {
188  differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
189  differences << " but not in previous files.\n";
190  } else {
191  productList_.insert(*i);
192  }
193  ++i;
194  } else if(i == e || (j != s && j->first < i->first)) {
195  if(j->second.present() && branchesMustMatch == BranchDescription::Strict) {
196  differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
197  differences << " but not in file '" << fileName << "'.\n";
198  }
199  ++j;
200  } else {
201  std::string difs = match(j->second, i->second, fileName, parametersMustMatch);
202  if(difs.empty()) {
203  if(parametersMustMatch == BranchDescription::Permissive) j->second.merge(i->second);
204  } else {
205  differences << difs;
206  }
207  ++i;
208  ++j;
209  }
210  }
212  return differences.str();
213  }
214 
215  static void
218  ConstBranchDescription const* branchDesc,
220  oMap[std::make_pair(TypeInBranchType(TypeID(type.TypeInfo()),
221  branchDesc->branchType()),
222  branchDesc)] = index;
223  }
224 
226  constProductList().clear();
227  transients_.get().branchIDToIndex_.clear();
229 
230  //NOTE it might be possible to remove the need for this temporary map because the productList is ordered by the
231  // BranchKey and for the same C++ class type the BranchKey will sort just like CompareTypeInBranchTypeConstBranchDescription
232  typedef TransientProductLookupMap::FillFromMap TempLookupMap;
233  TempLookupMap tempProductLookupMap;
234  TempLookupMap tempElementLookupMap;
235 
236  typedef std::set<std::string> UsedProcessNames;
237  UsedProcessNames usedProcessNames;
238  for(ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i, ++index) {
239  if(i->second.produced()) {
240  setProductProduced(i->second.branchType());
241  }
242 
243  //insert returns a pair<iterator, bool> and we want the address of the ConstBranchDescription that was created in the map
244  // this is safe since items in a map always retain their memory address
245  ConstBranchDescription const* pBD = &(constProductList().insert(std::make_pair(i->first, ConstBranchDescription(i->second))).first->second);
246 
247  transients_.get().branchIDToIndex_[i->second.branchID()] = index;
248 
249  usedProcessNames.insert(pBD->processName());
250 
251  Reflex::Type type(Reflex::Type::ByName(i->second.className()));
252  //only do the following if the data is supposed to be available in the event
253  if(i->second.present()) {
254  if(not bool(type)) {
255 
256  LogWarning("Missing Dictionary") << "Could not find a Reflex dictionary for class '" << i->second.className()
257  << "'. This class was registered as one which is supposed to be held by an Event, LuminosityBlock, or Run but will not be available. "
258  "Please check\n"
259  " 1) was a Reflex dictionary created for the class,\n"
260  " 2) if so was the package with the dictionary linked with all plugins that use that class,\n"
261  " 3) the file is from an old release and this data type has been removed from the present release.";
262  continue;
263  }
264  fillLookup(type, index, pBD, tempProductLookupMap);
265 
266  if(bool(type)) {
267  // Here we look in the object named "type" for a typedef
268  // named "value_type" and get the Reflex::Type for it.
269  // Then check to ensure the Reflex dictionary is defined
270  // for this value_type.
271  // I do not throw an exception here if the check fails
272  // because there are known cases where the dictionary does
273  // not exist and we do not need to support those cases.
274  Reflex::Type valueType;
275  if((is_RefVector(type, valueType) ||
276  is_PtrVector(type, valueType) ||
277  is_RefToBaseVector(type, valueType) ||
278  value_type_of(type, valueType))
279  && bool(valueType)) {
280 
281  fillLookup(valueType, index, pBD, tempElementLookupMap);
282 
283  // Repeat this for all public base classes of the value_type
284  std::vector<Reflex::Type> baseTypes;
285  public_base_classes(valueType, baseTypes);
286 
287  for(std::vector<Reflex::Type>::iterator iter = baseTypes.begin(),
288  iend = baseTypes.end();
289  iter != iend;
290  ++iter) {
291  fillLookup(*iter, index, pBD, tempElementLookupMap);
292  }
293  }
294  }
295  }
296  }
297  productLookup().fillFrom(tempProductLookupMap);
298  elementLookup().fillFrom(tempElementLookupMap);
299  }
300 
302  std::map<BranchID, ProductTransientIndex>::iterator itFind = transients_.get().branchIDToIndex_.find(iID);
303  if(itFind == transients_.get().branchIDToIndex_.end()) {
304  return kInvalidIndex;
305  }
306  return itFind->second;
307  }
308 
309  void ProductRegistry::print(std::ostream& os) const {
310  for(ProductList::const_iterator i = productList_.begin(), e = productList_.end(); i != e; ++i) {
311  os << i->second << "\n-----\n";
312  }
313  }
314 }
std::string const & processName() const
type
Definition: HCALResponse.h:22
int i
Definition: DBlmapReader.cc:9
unsigned short BranchListIndex
void public_base_classes(const Reflex::Type &type, std::vector< Reflex::Type > &baseTypes)
bool is_RefToBaseVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:145
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:128
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)
ProductList::size_type size() const
BranchType
Definition: BranchType.h:11
virtual void addCalled(BranchDescription const &, bool iFromListener)
Transient< Transients > transients_
ProductList const & productList() const
TransientProductLookupMap & elementLookup() const
bool combinable(BranchDescription const &a, BranchDescription const &b)
tuple result
Definition: query.py:137
void checkDictionaries(std::string const &name, bool noComponents=false)
Definition: ReflexTools.cc:263
int j
Definition: DBlmapReader.cc:9
std::vector< BranchDescription const * > allBranchDescriptions() const
boost::array< bool, NumBranchTypes > productProduced_
#define end
Definition: vmac.h:38
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:115
author Stefano ARGIRO author Bill Tanenbaum
void throwIfFrozen() const
void updateFromInput(ProductList const &other)
string s
Definition: asciidump.py:422
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)
void copyProduct(BranchDescription const &productdesc)
EventID const & max(EventID const &lh, EventID const &rh)
Definition: EventID.h:137