CMS 3D CMS Logo

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