![]() |
|
|||
File indexing completed on 2023-03-17 10:51:06
0001 #ifndef DataFormats_Provenance_ProductResolverIndexHelper_h 0002 #define DataFormats_Provenance_ProductResolverIndexHelper_h 0003 0004 /** \class edm::ProductResolverIndexHelper 0005 0006 This class assigns and gets the ProductResolverIndex 0007 associated with a type, module label, instance, and 0008 process. The ProductResolverIndex is used to tell the 0009 Principal where to store a ProductResolver and how to find 0010 it quickly. 0011 0012 One can also look up the same ProductResolverIndex's using 0013 the type or base type of an element in a container in the 0014 product (if the product is a container). In this case the 0015 KindOfType argument to the Principal::getByLabel function 0016 is ELEMENT_TYPE, whereas normally it is PRODUCT_TYPE. 0017 0018 There are also special ProductResolverIndex's generated 0019 where the process name is empty. These indexes refer 0020 to a special ProductResolvers that search for a matching 0021 product from the most recent process that has a matching 0022 type, label and instance. There is ProductResolverIndex 0023 generated for each type/label/instance combination which 0024 has at least one entry in the tables in this class. 0025 Both PRODUCT_TYPEs and ELEMENT_TYPEs get these special 0026 ProductResolvers. 0027 0028 The ProductResolverIndex for a particular product 0029 will not change during a process after the ProductRegistry 0030 has been frozen. Nor will any of the other member data 0031 of this class. Multiple threads can access it concurrently 0032 without problems. The ProductResolverIndexes can be safely 0033 cached in InputTags and possibly other places, because 0034 they never change within a process. The ProductResolverIndex 0035 for a particular product is not intended to be persistent 0036 and will be different in different processes. 0037 0038 The ProductResolverIndex is used to order the placement of 0039 the ProductResolvers in the Principal that are either 0040 present in the input or produced in the current process. 0041 Be aware that there are other ProductResolvers for products 0042 that come after ProductResolvers placed by this class. 0043 For example, the placement of dropped products 0044 is not handled by this class, instead by the ProductRegistry. 0045 The reason for this distinction is that those other 0046 ProductResolvers can change and be added as a process runs. 0047 The content of this class never changes after the 0048 ProductRegistry is frozen. 0049 0050 \author W. David Dagenhart, created 10 December, 2012 0051 0052 */ 0053 0054 #include "FWCore/Utilities/interface/ProductResolverIndex.h" 0055 #include "FWCore/Utilities/interface/ProductKindOfType.h" 0056 #include "FWCore/Utilities/interface/TypeID.h" 0057 #include "FWCore/Utilities/interface/propagate_const.h" 0058 0059 #include <iosfwd> 0060 #include <memory> 0061 #include <set> 0062 #include <string> 0063 #include <vector> 0064 #include <tuple> 0065 #include <unordered_map> 0066 0067 namespace edm { 0068 0069 class TypeWithDict; 0070 0071 namespace productholderindexhelper { 0072 // The next function supports views. For the given wrapped type, 0073 // which must be Wrapper<T>, 0074 // this function returns the type of the contained type of T. 0075 // If the type is not a recongnized container, it returns 0076 // a TypeID(typeid(void)). 0077 TypeID getContainedTypeFromWrapper(TypeID const& wrappedtypeID, std::string const& className); 0078 0079 // The next function supports views. For the given type T, 0080 // this function returns the type of the contained type of T. 0081 // If the type is not a recongnized container, it returns 0082 // a TypeID(typeid(void)). 0083 // This calls getContainedTypefromWrapped internally 0084 // If the TypeID for the wrapped type is already available, 0085 // it is faster to call getContainedTypeFromWrapper directly. 0086 TypeID getContainedType(TypeID const& typeID); 0087 0088 bool typeIsViewCompatible(TypeID const& requestedViewType, 0089 TypeID const& wrappedtypeID, 0090 std::string const& className); 0091 } // namespace productholderindexhelper 0092 0093 class ProductResolverIndexHelper { 0094 public: 0095 ProductResolverIndexHelper(); 0096 0097 // The accessors below return a ProductResolverIndex that matches 0098 // the arguments or a set of matching indexes using the Matches 0099 // class. A returned index can have a value that indicates that it 0100 // is invalid or ambiguous and the client should check for these 0101 // values before using the index (see ProductResolverIndex.h). 0102 0103 // If no matches are found or the ProductResolverIndexHelper 0104 // has not been frozen yet, then an invalid index or a Matches 0105 // object with numberOfMatches equal to 0 will be returned. 0106 0107 // The ambiguous values can occur when the kind of type is ELEMENT_TYPE 0108 // type. ELEMENT_TYPE is the type or base type of an object 0109 // stored in a container that is the product. These types are used 0110 // with data requests that use Views. For PRODUCT_TYPE types, ambiguity 0111 // is not possible. 0112 0113 // The next function returns the index for the one group that 0114 // matches the type, module label, instance, and process. 0115 // The 3 pointer arguments must point to C style strings terminated 0116 // by a '\0' with the one following possible exception. If the 0117 // process pointer is null or the process string empty, then 0118 // this returns the index of the special ProductResolver that 0119 // knows how to search for the product matching the type, module 0120 // label, and instance and which is from the most recent process. 0121 ProductResolverIndex index(KindOfType kindOfType, 0122 TypeID const& typeID, 0123 char const* moduleLabel, 0124 char const* instance, 0125 char const* process = nullptr) const; 0126 0127 using ModulesToIndiciesMap = 0128 std::unordered_multimap<std::string, std::tuple<TypeID const*, const char*, ProductResolverIndex>>; 0129 ModulesToIndiciesMap indiciesForModulesInProcess(const std::string& iProcessName) const; 0130 0131 class Matches { 0132 public: 0133 Matches(ProductResolverIndexHelper const* productResolverIndexHelper, 0134 unsigned int startInIndexAndNames, 0135 unsigned int numberOfMatches); 0136 0137 ProductResolverIndex index(unsigned int i) const; 0138 unsigned int numberOfMatches() const { return numberOfMatches_; } 0139 bool isFullyResolved(unsigned int i) const; 0140 char const* moduleLabel(unsigned int i) const; 0141 char const* productInstanceName(unsigned int i) const; 0142 char const* processName(unsigned int i) const; 0143 0144 private: 0145 ProductResolverIndexHelper const* productResolverIndexHelper_; 0146 unsigned int startInIndexAndNames_; 0147 unsigned int numberOfMatches_; 0148 }; 0149 0150 // Return ProductResolverIndex's for all product holders that 0151 // match the type, module label, and product instance name. 0152 // The pointer arguments must be C style strings terminated 0153 // by a '\0'. 0154 Matches relatedIndexes(KindOfType kindOfType, 0155 TypeID const& typeID, 0156 char const* moduleLabel, 0157 char const* instance) const; 0158 0159 // Return indexes for all groups that match the type. 0160 Matches relatedIndexes(KindOfType kindOfType, TypeID const& typeID) const; 0161 0162 // This will throw if called after the object is frozen. 0163 // The typeID must be for a type with a dictionary 0164 // (the calling function is expected to check that) 0165 // The pointer arguments must point at C style strings 0166 // terminated by '\0'. 0167 // 1. This creates an entry and new ProductResolverIndex for 0168 // the product if it does not already exist. If it 0169 // does exist then it throws. 0170 // 2. If it does not already exist, this will create an 0171 // entry and new ProductResolverIndex for the ProductResolver 0172 // that will search for the matching type, label, and 0173 // instance for the most recent process (internally indicated 0174 // by an empty process string). 0175 // This will then loop over the contained class (if it exists) 0176 // and the base classes of the contained class. 0177 // 1. If the matching type, label, instance, and process 0178 // already exist then that entry is modified and marked 0179 // ambiguous. If not, it inserts an entry which uses the same 0180 // ProductResolverIndex as the containing product. 0181 // 2. If it does not already exist it inserts a new 0182 // entry with a new ProductResolverIndex for the case 0183 // which searches for the most recent process. 0184 ProductResolverIndex insert(TypeID const& typeID, 0185 char const* moduleLabel, 0186 char const* instance, 0187 char const* process, 0188 TypeID const& containedTypeID, 0189 std::vector<TypeID>* baseTypesOfContainedType); 0190 0191 ProductResolverIndex insert(TypeID const& typeID, 0192 char const* moduleLabel, 0193 char const* instance, 0194 char const* process); 0195 0196 // Before the object is frozen the accessors above will 0197 // fail to find a match. Once frozen, no more new entries 0198 // can be added with insert. 0199 void setFrozen(); 0200 0201 std::vector<std::string> const& lookupProcessNames() const; 0202 0203 class Range { 0204 public: 0205 Range(unsigned int begin, unsigned int end) : begin_(begin), end_(end) {} 0206 unsigned int begin() const { return begin_; } 0207 unsigned int end() const { return end_; } 0208 0209 private: 0210 unsigned int begin_; 0211 unsigned int end_; 0212 }; 0213 0214 class IndexAndNames { 0215 public: 0216 IndexAndNames(ProductResolverIndex index, unsigned int start, unsigned int startProcess) 0217 : index_(index), startInBigNamesContainer_(start), startInProcessNames_(startProcess) {} 0218 ProductResolverIndex index() const { return index_; } 0219 unsigned int startInBigNamesContainer() const { return startInBigNamesContainer_; } 0220 unsigned int startInProcessNames() const { return startInProcessNames_; } 0221 0222 private: 0223 ProductResolverIndex index_; 0224 unsigned int startInBigNamesContainer_; 0225 unsigned int startInProcessNames_; 0226 }; 0227 0228 unsigned int beginElements() const { return beginElements_; } 0229 std::vector<TypeID> const& sortedTypeIDs() const { return sortedTypeIDs_; } 0230 std::vector<Range> const& ranges() const { return ranges_; } 0231 std::vector<IndexAndNames> const& indexAndNames() const { return indexAndNames_; } 0232 std::vector<char> const& processNames() const { return processNames_; } 0233 0234 // The next few functions are intended for internal use 0235 // but are public so tests can use them also. 0236 0237 unsigned int indexToIndexAndNames(KindOfType kindOfType, 0238 TypeID const& typeID, 0239 char const* moduleLabel, 0240 char const* instance, 0241 char const* process) const; 0242 0243 // Returns the index into sortedTypeIDs_. Returns the maximum unsigned 0244 // int value if the type is not there. 0245 unsigned int indexToType(KindOfType kindOfType, TypeID const& typeID) const; 0246 0247 // Returns the index of the process name in processNames_. Returns the 0248 // maximum unsigned int value if the process name is not found. 0249 unsigned int processIndex(char const* process) const; 0250 0251 // This will throw if it detects problems, but unless there is a bug 0252 // there should never be any. Mostly it is checking for things which 0253 // might cause out of bounds errors when accessing the vectors. 0254 void sanityCheck() const; 0255 0256 ProductResolverIndex nextIndexValue() const { return nextIndexValue_; } 0257 0258 // For debugging only 0259 void print(std::ostream& os) const; 0260 0261 private: 0262 // Next available value for a ProductResolverIndex. This just 0263 // increments by one each time a new value is assigned. 0264 ProductResolverIndex nextIndexValue_; 0265 0266 // This is an index into sortedTypeIDs_ that tells where 0267 // the entries corresponding to types of elements in containers 0268 // start. 0269 unsigned int beginElements_; 0270 0271 // Sorted by putting all the product entries first and 0272 // then the element entries. Then sorted by TypeID value. 0273 // Most lookups start here by finding the TypeID and 0274 // then using its position to find the corresponding Range 0275 // in the ranges_ vector below. 0276 std::vector<TypeID> sortedTypeIDs_; 0277 0278 // There is a one to one correspondence between this vector 0279 // and sortedTypeIDs_ and the corresponding elements appear 0280 // in the same order. Each Range object holds the beginning and 0281 // end of the corresponding elements in the indexAndNames_ 0282 // vector below. 0283 std::vector<Range> ranges_; 0284 0285 // Each element of this vector contains a ProductResolverIndex. 0286 // It also contains indexes into vectors of characters that 0287 // hold the corresponding moduleLabel, instance, and process 0288 // name. Note this is sorted with product entries first then 0289 // element entries, then by TypeID, then by moduleLabel, 0290 // then by instance, and finally by process. Note that in 0291 // a subset of entries that have matching type/label/instance 0292 // the entry with an empty process name will always be the 0293 // first process and startInProcessNames_ will always be 0 0294 // for the empty process name. 0295 std::vector<IndexAndNames> indexAndNames_; 0296 0297 // These contain C style strings terminated 0298 // by '\0' all concatenated together. In the 0299 // first vector the strings come in pairs, 0300 // always module label then instance. The pairs 0301 // are ordered the same as the IndexAndNames 0302 // vector. Within a TypeID, the moduleLabel/instance 0303 // pair is not duplicated if it appears multiple times. 0304 // The second vector contains all the process names 0305 // in alphabetical order with no duplication. The 0306 // first element is always the empty string. 0307 std::vector<char> bigNamesContainer_; 0308 std::vector<char> processNames_; 0309 0310 // Duplicates the entries in processNames_ in 0311 // a convenient format. 0312 std::vector<std::string> lookupProcessNames_; 0313 0314 // The rest of the data members are for temporary use 0315 // while the data structure is being filled. 0316 0317 class Item { 0318 public: 0319 Item(KindOfType kindOfType, 0320 TypeID const& typeID, 0321 std::string const& moduleLabel, 0322 std::string const& instance, 0323 std::string const& process, 0324 ProductResolverIndex index); 0325 KindOfType kindOfType() const { return kindOfType_; } 0326 TypeID const& typeID() const { return typeID_; } 0327 std::string const& moduleLabel() const { return moduleLabel_; } 0328 std::string const& instance() const { return instance_; } 0329 std::string const& process() const { return process_; } 0330 ProductResolverIndex index() const { return index_; } 0331 0332 void clearProcess() { process_.clear(); } 0333 void setIndex(ProductResolverIndex v) { index_ = v; } 0334 0335 bool operator<(Item const& right) const; 0336 0337 private: 0338 KindOfType kindOfType_; 0339 TypeID typeID_; 0340 std::string moduleLabel_; 0341 std::string instance_; 0342 std::string process_; 0343 ProductResolverIndex index_; 0344 }; 0345 0346 edm::propagate_const<std::unique_ptr<std::set<Item>>> items_; 0347 0348 edm::propagate_const<std::unique_ptr<std::set<std::string>>> processItems_; 0349 }; 0350 } // namespace edm 0351 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.2.1 LXR engine. The LXR team |
![]() ![]() |