CMS 3D CMS Logo

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