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