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