CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ProductHolderIndexHelper.h
Go to the documentation of this file.
1 #ifndef DataFormats_Provenance_ProductHolderIndexHelper_h
2 #define DataFormats_Provenance_ProductHolderIndexHelper_h
3 
58 
59 #include <iosfwd>
60 #include <memory>
61 #include <set>
62 #include <string>
63 #include <vector>
64 
65 namespace edm {
66 
67  namespace productholderindexhelper {
68  // The next function supports views. For the given wrapped type,
69  // which must be Wrapper<T>,
70  // this function returns the type of the contained type of T.
71  // If the type is not a recongnized container, it returns
72  // a TypeID(typeid(void)).
73  TypeID getContainedTypeFromWrapper(TypeID const& wrappedtypeID, std::string const& className);
74 
75  // The next function supports views. For the given type T,
76  // this function returns the type of the contained type of T.
77  // If the type is not a recongnized container, it returns
78  // a TypeID(typeid(void)).
79  // This calls getContainedTypefromWrapped internally
80  // If the TypeID for the wrapped type is already available,
81  // it is faster to call getContainedTypeFromWrapper directly.
82  TypeID getContainedType(TypeID const& typeID);
83  }
84 
86  public:
87 
89 
90  // The accessors below return a ProductHolderIndex that matches
91  // the arguments or a set of matching indexes using the Matches
92  // class. A returned index can have a value that indicates that it
93  // is invalid or ambiguous and the client should check for these
94  // values before using the index (see ProductIndexHolder.h).
95 
96  // If no matches are found or the ProductHolderIndexHelper
97  // has not been frozen yet, then an invalid index or a Matches
98  // object with numberOfMatches equal to 0 will be returned.
99 
100  // The ambiguous values can occur when the kind of type is ELEMENT_TYPE
101  // type. ELEMENT_TYPE is the type or base type of an object
102  // stored in a container that is the product. These types are used
103  // with data requests that use Views. For PRODUCT_TYPE types, ambiguity
104  // is not possible.
105 
106  // The next function returns the index for the one group that
107  // matches the type, module label, instance, and process.
108  // The 3 pointer arguments must point to C style strings terminated
109  // by a '\0' with the one following possible exception. If the
110  // process pointer is null or the process string empty, then
111  // this returns the index of the special ProductHolder that
112  // knows how to search for the product matching the type, module
113  // label, and instance and which is from the most recent process.
115  TypeID const& typeID,
116  char const* moduleLabel,
117  char const* instance,
118  char const* process = 0) const;
119 
120  class Matches {
121  public:
122  Matches(ProductHolderIndexHelper const* productHolderIndexHelper,
123  unsigned int startInIndexAndNames,
124  unsigned int numberOfMatches);
125 
126  ProductHolderIndex index(unsigned int i) const;
127  unsigned int numberOfMatches() const { return numberOfMatches_; }
128  bool isFullyResolved(unsigned int i) const;
129  char const* moduleLabel(unsigned int i) const;
130  char const* processName(unsigned int i) const;
131  private:
133  unsigned int startInIndexAndNames_;
134  unsigned int numberOfMatches_;
135  };
136 
137  // Return ProductHolderIndex's for all product holders that
138  // match the type, module label, and product instance name.
139  // The pointer arguments must be C style strings terminated
140  // by a '\0'.
141  Matches
142  relatedIndexes(KindOfType kindOfType,
143  TypeID const& typeID,
144  char const* moduleLabel,
145  char const* instance) const;
146 
147  // Return indexes for all groups that match the type.
148  Matches
149  relatedIndexes(KindOfType kindOfType,
150  TypeID const& typeID) const;
151 
152  // This will throw if called after the object is frozen.
153  // The typeID must be for a type with a dictionary
154  // (the calling function is expected to check that)
155  // The pointer arguments must point at C style strings
156  // terminated by '\0'.
157  // 1. This creates an entry and new ProductHolderIndex for
158  // the product if it does not already exist. If it
159  // does exist then it throws.
160  // 2. If it does not already exist, this will create an
161  // entry and new ProductHolderIndex for the ProductHolder
162  // that will search for the matching type, label, and
163  // instance for the most recent process (internally indicated
164  // by an empty process string).
165  // This will then loop over the contained class (if it exists)
166  // and the base classes of the contained class.
167  // 1. If the matching type, label, instance, and process
168  // already exist then that entry is modified and marked
169  // ambiguous. If not, it inserts an entry which uses the same
170  // ProductHolderIndex as the containing product.
171  // 2. If it does not already exist it inserts a new
172  // entry with a new ProductHolderIndex for the case
173  // which searches for the most recent process.
175  insert(TypeID const& typeID,
176  char const* moduleLabel,
177  char const* instance,
178  char const* process,
179  TypeID const& containedTypeID);
180 
182  insert(TypeID const& typeID,
183  char const* moduleLabel,
184  char const* instance,
185  char const* process) {
186  return insert(typeID, moduleLabel, instance, process, productholderindexhelper::getContainedType(typeID));
187  }
188 
189  // Before the object is frozen the accessors above will
190  // fail to find a match. Once frozen, no more new entries
191  // can be added with insert.
192  void setFrozen();
193 
194  std::vector<std::string> const& lookupProcessNames() const;
195 
196  class Range {
197  public:
198  Range(unsigned int begin, unsigned int end) : begin_(begin), end_(end) { }
199  unsigned int begin() const { return begin_; }
200  unsigned int end() const { return end_; }
201  private:
202  unsigned int begin_;
203  unsigned int end_;
204  };
205 
207  public:
208  IndexAndNames(ProductHolderIndex index, unsigned int start, unsigned int startProcess) :
209  index_(index), startInBigNamesContainer_(start), startInProcessNames_(startProcess) { }
210  ProductHolderIndex index() const { return index_; }
211  unsigned int startInBigNamesContainer() const { return startInBigNamesContainer_; }
212  unsigned int startInProcessNames() const { return startInProcessNames_; }
213  private:
216  unsigned int startInProcessNames_;
217  };
218 
219  unsigned int beginElements() const { return beginElements_; }
220  std::vector<TypeID> const& sortedTypeIDs() const { return sortedTypeIDs_; }
221  std::vector<Range> const& ranges() const { return ranges_; }
222  std::vector<IndexAndNames> const& indexAndNames() const { return indexAndNames_; }
223  std::vector<char> const& processNames() const { return processNames_; }
224 
225  // The next few functions are intended for internal use
226  // but are public so tests can use them also.
227 
228  unsigned int indexToIndexAndNames(KindOfType kindOfType,
229  TypeID const& typeID,
230  char const* moduleLabel,
231  char const* instance,
232  char const* process) const;
233 
234  // Returns the index into sortedTypeIDs_. Returns the maximum unsigned
235  // int value if the type is not there.
236  unsigned int indexToType(KindOfType kindOfType, TypeID const& typeID) const;
237 
238  // Returns the index of the process name in processNames_. Returns the
239  // maximum unsigned int value if the process name is not found.
240  unsigned int processIndex(char const* process) const;
241 
242  // This will throw if it detects problems, but unless there is a bug
243  // there should never be any. Mostly it is checking for things which
244  // might cause out of bounds errors when accessing the vectors.
245  void sanityCheck() const;
246 
248 
249  // For debugging only
250  void print(std::ostream& os) const;
251 
252  private:
253 
254  // Next available value for a ProductHolderIndex. This just
255  // increments by one each time a new value is assigned.
257 
258  // This is an index into sortedTypeIDs_ that tells where
259  // the entries corresponding to types of elements in containers
260  // start.
261  unsigned int beginElements_;
262 
263  // Sorted by putting all the product entries first and
264  // then the element entries. Then sorted by TypeID value.
265  // Most lookups start here by finding the TypeID and
266  // then using its position to find the corresponding Range
267  // in the ranges_ vector below.
268  std::vector<TypeID> sortedTypeIDs_;
269 
270  // There is a one to one correspondence between this vector
271  // and sortedTypeIDs_ and the corresponding elements appear
272  // in the same order. Each Range object holds the beginning and
273  // end of the corresponding elements in the indexAndNames_
274  // vector below.
275  std::vector<Range> ranges_;
276 
277  // Each element of this vector contains a ProductHolderIndex.
278  // It also contains indexes into vectors of characters that
279  // hold the corresponding moduleLabel, instance, and process
280  // name. Note this is sorted with product entries first then
281  // element entries, then by TypeID, then by moduleLabel,
282  // then by instance, and finally by process. Note that in
283  // a subset of entries that have matching type/label/instance
284  // the entry with an empty process name will always be the
285  // first process and startInProcessNames_ will always be 0
286  // for the empty process name.
287  std::vector<IndexAndNames> indexAndNames_;
288 
289  // These contain C style strings terminated
290  // by '\0' all concatenated together. In the
291  // first vector the strings come in pairs,
292  // always module label then instance. The pairs
293  // are ordered the same as the IndexAndNames
294  // vector. Within a TypeID, the moduleLabel/instance
295  // pair is not duplicated if it appears multiple times.
296  // The second vector contains all the process names
297  // in alphabetical order with no duplication. The
298  // first element is always the empty string.
299  std::vector<char> bigNamesContainer_;
300  std::vector<char> processNames_;
301 
302  // Duplicates the entries in processNames_ in
303  // a convenient format.
304  std::vector<std::string> lookupProcessNames_;
305 
306  // The rest of the data members are for temporary use
307  // while the data structure is being filled.
308 
309  class Item {
310  public:
311  Item(KindOfType kindOfType,
312  TypeID const& typeID,
313  std::string const& moduleLabel,
314  std::string const& instance,
315  std::string const& process,
316  ProductHolderIndex index);
317  KindOfType kindOfType() const { return kindOfType_; }
318  TypeID const& typeID() const { return typeID_; }
319  std::string const& moduleLabel() const { return moduleLabel_; }
320  std::string const& instance() const { return instance_; }
321  std::string const& process() const { return process_; }
322  ProductHolderIndex index() const { return index_; }
323 
324  void clearProcess() { process_.clear(); }
326 
327  bool operator<(Item const& right) const;
328 
329  private:
336  };
337 
339 
341  };
342 }
343 #endif
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
TypeID getContainedType(TypeID const &typeID)
int i
Definition: DBlmapReader.cc:9
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
TypeID getContainedTypeFromWrapper(TypeID const &wrappedtypeID, std::string const &className)
char const * moduleLabel(unsigned int i) const
static PFTauRenderPlugin instance
ProductHolderIndexHelper const * productHolderIndexHelper_
ProductHolderIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
std::vector< IndexAndNames > indexAndNames_
std::vector< Range > const & ranges() const
Range(unsigned int begin, unsigned int end)
char const * processName(unsigned int i) const
void print(std::ostream &os) const
unsigned int ProductHolderIndex
std::vector< std::string > lookupProcessNames_
Matches(ProductHolderIndexHelper const *productHolderIndexHelper, unsigned int startInIndexAndNames, unsigned int numberOfMatches)
ProductHolderIndex nextIndexValue() const
bool operator<(Item const &right) const
unsigned int indexToType(KindOfType kindOfType, TypeID const &typeID) const
ProductHolderIndex index(unsigned int i) const
unsigned int processIndex(char const *process) const
std::string const & moduleLabel() const
IndexAndNames(ProductHolderIndex index, unsigned int start, unsigned int startProcess)
ProductHolderIndex insert(TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process, TypeID const &containedTypeID)
std::vector< char > const & processNames() const
edm::propagate_const< std::unique_ptr< std::set< Item > > > items_
edm::propagate_const< std::unique_ptr< std::set< std::string > > > processItems_
std::vector< std::string > const & lookupProcessNames() const
std::vector< IndexAndNames > const & indexAndNames() const
std::vector< TypeID > const & sortedTypeIDs() const
Item(KindOfType kindOfType, TypeID const &typeID, std::string const &moduleLabel, std::string const &instance, std::string const &process, ProductHolderIndex index)
tuple process
Definition: LaserDQM_cfg.py:3
ProductHolderIndex insert(TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process)
std::string className(const T &t)
Definition: ClassName.h:30
unsigned int indexToIndexAndNames(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process) const