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  char const* moduleLabel(unsigned int i) const;
140  char const* productInstanceName(unsigned int i) const;
141  char const* processName(unsigned int i) const;
142 
143  private:
145  unsigned int startInIndexAndNames_;
146  unsigned int numberOfMatches_;
147  };
148 
149  // Return ProductResolverIndex's for all product holders that
150  // match the type, module label, and product instance name.
151  // The pointer arguments must be C style strings terminated
152  // by a '\0'.
153  Matches relatedIndexes(KindOfType kindOfType,
154  TypeID const& typeID,
155  char const* moduleLabel,
156  char const* instance) const;
157 
158  // Return indexes for all groups that match the type.
159  Matches relatedIndexes(KindOfType kindOfType, TypeID const& typeID) const;
160 
161  // This will throw if called after the object is frozen.
162  // The typeID must be for a type with a dictionary
163  // (the calling function is expected to check that)
164  // The pointer arguments must point at C style strings
165  // terminated by '\0'.
166  // 1. This creates an entry and new ProductResolverIndex for
167  // the product if it does not already exist. If it
168  // does exist then it throws.
169  // 2. If it does not already exist, this will create an
170  // entry and new ProductResolverIndex for the ProductResolver
171  // that will search for the matching type, label, and
172  // instance for the most recent process (internally indicated
173  // by an empty process string).
174  // This will then loop over the contained class (if it exists)
175  // and the base classes of the contained class.
176  // 1. If the matching type, label, instance, and process
177  // already exist then that entry is modified and marked
178  // ambiguous. If not, it inserts an entry which uses the same
179  // ProductResolverIndex as the containing product.
180  // 2. If it does not already exist it inserts a new
181  // entry with a new ProductResolverIndex for the case
182  // which searches for the most recent process.
183  ProductResolverIndex insert(TypeID const& typeID,
184  char const* moduleLabel,
185  char const* instance,
186  char const* process,
187  TypeID const& containedTypeID,
188  std::vector<TypeID>* baseTypesOfContainedType);
189 
190  ProductResolverIndex insert(TypeID const& typeID,
191  char const* moduleLabel,
192  char const* instance,
193  char const* process);
194 
195  // Before the object is frozen the accessors above will
196  // fail to find a match. Once frozen, no more new entries
197  // can be added with insert.
198  void setFrozen();
199 
200  std::vector<std::string> const& lookupProcessNames() const;
201 
202  class Range {
203  public:
204  Range(unsigned int begin, unsigned int end) : begin_(begin), end_(end) {}
205  unsigned int begin() const { return begin_; }
206  unsigned int end() const { return end_; }
207 
208  private:
209  unsigned int begin_;
210  unsigned int end_;
211  };
212 
214  public:
215  IndexAndNames(ProductResolverIndex index, unsigned int start, unsigned int startProcess)
217  ProductResolverIndex index() const { return index_; }
218  unsigned int startInBigNamesContainer() const { return startInBigNamesContainer_; }
219  unsigned int startInProcessNames() const { return startInProcessNames_; }
220 
221  private:
224  unsigned int startInProcessNames_;
225  };
226 
227  unsigned int beginElements() const { return beginElements_; }
228  std::vector<TypeID> const& sortedTypeIDs() const { return sortedTypeIDs_; }
229  std::vector<Range> const& ranges() const { return ranges_; }
230  std::vector<IndexAndNames> const& indexAndNames() const { return indexAndNames_; }
231  std::vector<char> const& processNames() const { return processNames_; }
232 
233  // The next few functions are intended for internal use
234  // but are public so tests can use them also.
235 
236  unsigned int indexToIndexAndNames(KindOfType kindOfType,
237  TypeID const& typeID,
238  char const* moduleLabel,
239  char const* instance,
240  char const* process) const;
241 
242  // Returns the index into sortedTypeIDs_. Returns the maximum unsigned
243  // int value if the type is not there.
244  unsigned int indexToType(KindOfType kindOfType, TypeID const& typeID) const;
245 
246  // Returns the index of the process name in processNames_. Returns the
247  // maximum unsigned int value if the process name is not found.
248  unsigned int processIndex(char const* process) const;
249 
250  // This will throw if it detects problems, but unless there is a bug
251  // there should never be any. Mostly it is checking for things which
252  // might cause out of bounds errors when accessing the vectors.
253  void sanityCheck() const;
254 
256 
257  // For debugging only
258  void print(std::ostream& os) const;
259 
260  private:
261  // Next available value for a ProductResolverIndex. This just
262  // increments by one each time a new value is assigned.
264 
265  // This is an index into sortedTypeIDs_ that tells where
266  // the entries corresponding to types of elements in containers
267  // start.
268  unsigned int beginElements_;
269 
270  // Sorted by putting all the product entries first and
271  // then the element entries. Then sorted by TypeID value.
272  // Most lookups start here by finding the TypeID and
273  // then using its position to find the corresponding Range
274  // in the ranges_ vector below.
275  std::vector<TypeID> sortedTypeIDs_;
276 
277  // There is a one to one correspondence between this vector
278  // and sortedTypeIDs_ and the corresponding elements appear
279  // in the same order. Each Range object holds the beginning and
280  // end of the corresponding elements in the indexAndNames_
281  // vector below.
282  std::vector<Range> ranges_;
283 
284  // Each element of this vector contains a ProductResolverIndex.
285  // It also contains indexes into vectors of characters that
286  // hold the corresponding moduleLabel, instance, and process
287  // name. Note this is sorted with product entries first then
288  // element entries, then by TypeID, then by moduleLabel,
289  // then by instance, and finally by process. Note that in
290  // a subset of entries that have matching type/label/instance
291  // the entry with an empty process name will always be the
292  // first process and startInProcessNames_ will always be 0
293  // for the empty process name.
294  std::vector<IndexAndNames> indexAndNames_;
295 
296  // These contain C style strings terminated
297  // by '\0' all concatenated together. In the
298  // first vector the strings come in pairs,
299  // always module label then instance. The pairs
300  // are ordered the same as the IndexAndNames
301  // vector. Within a TypeID, the moduleLabel/instance
302  // pair is not duplicated if it appears multiple times.
303  // The second vector contains all the process names
304  // in alphabetical order with no duplication. The
305  // first element is always the empty string.
306  std::vector<char> bigNamesContainer_;
307  std::vector<char> processNames_;
308 
309  // Duplicates the entries in processNames_ in
310  // a convenient format.
311  std::vector<std::string> lookupProcessNames_;
312 
313  // The rest of the data members are for temporary use
314  // while the data structure is being filled.
315 
316  class Item {
317  public:
319  TypeID const& typeID,
320  std::string const& moduleLabel,
321  std::string const& instance,
322  std::string const& process,
324  KindOfType kindOfType() const { return kindOfType_; }
325  TypeID const& typeID() const { return typeID_; }
326  std::string const& moduleLabel() const { return moduleLabel_; }
327  std::string const& instance() const { return instance_; }
328  std::string const& process() const { return process_; }
329  ProductResolverIndex index() const { return index_; }
330 
331  void clearProcess() { process_.clear(); }
333 
334  bool operator<(Item const& right) const;
335 
336  private:
343  };
344 
346 
348  };
349 } // namespace edm
350 #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