ATLAS Offline Software
Loading...
Searching...
No Matches
IdentifierHashCalc.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
6#define MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
7
8/***************************************************************************
9 * Identifier hashes
10 * -----------------------------------------
11 *
12 * Author : Martin Woudstra
13 * Creation Date: 7 May 2004
14 * Last Update : 9 May 2005
15 ***************************************************************************/
16
20
21#include "GaudiKernel/MsgStream.h"
23
24#include <limits.h>
25#include <iostream>
26#include <iomanip>
27
28template <class T>
30public:
31 //
32 // Nested types
33 //
37 enum { NFIELDS = T::NFIELDS, NMAX=UINT_MAX };
39 typedef T IdFieldsType;
41 typedef typename T::IdentifierType IdType;
43 typedef typename T::HashType HashType;
44 //
45 // Member functions
46 //
51 explicit IdentifierHashCalc( const T& idFields );
53 void clear();
55 unsigned int size() const;
57 bool checkValidity() const;
59 bool addEntry( const IdType& id );
61 void setFieldLimits( unsigned int fieldIndex, int fieldMin, int fieldMax );
63 HashType getHash( const IdType& id ) const;
65 IdType getIdentifier( const HashType& idHash ) const;
67 void dump( std::ostream& os = std::cout ) const;
69 std::string dumpToString() const;
70private:
71 bool isInRange( const T& idFields ) const;
72 void update();
75 unsigned int m_fieldsSize[NFIELDS];
76 unsigned int m_fieldsFactor[NFIELDS];
77 mutable T m_idFields;
78};
79
80template <class T>
82 clear();
83}
84
85template <class T>
86inline IdentifierHashCalc<T>::IdentifierHashCalc( const T& idFields )
87 : m_idFields(idFields)
88{
89 clear();
90}
91
92template <class T>
93inline bool IdentifierHashCalc<T>::isInRange( const T& idFields ) const {
94 for ( unsigned int i = 0; i < NFIELDS; ++i ) {
95 if ( idFields[i] < m_fieldsMin[i] || idFields[i] > m_fieldsMax[i] ) return false;
96 }
97 return true;
98}
99
100template <class T>
102IdentifierHashCalc<T>::getHash( const IdType& id ) const {
103 m_idFields.setAll( id );
104 if ( !isInRange( m_idFields ) ) return T::defaultHash();
105 unsigned int hash = m_idFields[0] - m_fieldsMin[0];
106 for ( unsigned int i = 1; i < NFIELDS; ++i ) {
107 hash += m_fieldsFactor[i-1] * ( m_idFields[i] - m_fieldsMin[i] );
108 }
109 return HashType(hash);
110}
111
112template <class T>
114IdentifierHashCalc<T>::getIdentifier( const HashType& idHash ) const {
115 int fields[NFIELDS];
116 fields[0] = m_fieldsMin[0] + ( idHash % m_fieldsSize[0] );
117 for ( unsigned int i = 1; i < NFIELDS; ++i ) {
118 fields[i] = m_fieldsMin[i] + ( ( idHash / m_fieldsFactor[i-1] ) % m_fieldsSize[i] );
119 }
120 m_idFields.setAll( fields );
121 if ( !isInRange( m_idFields ) ) return IdType();
122 return m_idFields.getId();
123}
124
125template <class T>
127 // update sizes and field factors
128 m_fieldsSize[0] = m_fieldsMax[0] - m_fieldsMin[0] + 1;
129 m_fieldsFactor[0] = m_fieldsSize[0];
130 for ( unsigned int i = 1; i < NFIELDS; ++i ) {
131 m_fieldsSize[i] = m_fieldsMax[i] - m_fieldsMin[i] + 1;
132 m_fieldsFactor[i] = m_fieldsFactor[i-1] * m_fieldsSize[i];
133 }
134}
135
136template <class T>
137inline bool IdentifierHashCalc<T>::addEntry( const IdType& id ) {
138 if ( !T::isValid( id ) ) return false;
139 // set ranges
140 m_idFields.setAll( id );
141 bool bChanged = false;
142 for ( unsigned int i = 0; i < NFIELDS; ++i ) {
143 if ( m_idFields[i] < m_fieldsMin[i] ) {
144 m_fieldsMin[i] = m_idFields[i];
145 bChanged = true;
146 }
147 if ( m_idFields[i] > m_fieldsMax[i] ) {
148 m_fieldsMax[i] = m_idFields[i];
149 bChanged = true;
150 }
151 }
152 if ( bChanged ) update();
153 return true;
154}
155
156template <class T>
157void IdentifierHashCalc<T>::setFieldLimits( unsigned int fieldIndex, int fieldMin, int fieldMax ) {
158 if ( fieldIndex >= NFIELDS ) return;
159 if ( fieldMin > fieldMax ) return;
160 bool bChanged = false;
161 if ( fieldMin != m_fieldsMin[fieldIndex] ) {
162 m_fieldsMin[fieldIndex] = fieldMin;
163 bChanged = true;
164 }
165 if ( fieldMax != m_fieldsMax[fieldIndex] ) {
166 m_fieldsMax[fieldIndex] = fieldMax;
167 bChanged = true;
168 }
169 if ( bChanged ) update();
170}
171
172template <class T>
174 for ( unsigned int i = 0; i < NFIELDS; ++i ) {
175 m_fieldsMin[i] = INT_MAX;
176 m_fieldsMax[i] = INT_MIN;
177 m_fieldsSize[i] = 0;
178 m_fieldsFactor[i] = 0;
179 }
180}
181
182template <class T>
183inline unsigned int IdentifierHashCalc<T>::size() const {
184 return m_fieldsFactor[NFIELDS - 1];
185}
186
187template <class T>
189 // check that table is non-empty
190 if ( !size() ) {
191 MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
192 log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() Table is empty."<<endmsg;
193 return false;
194 }
195 // check that tables are each other's inverse
196 unsigned int nErrors = 0;
197#ifdef IDENTIFIERHASHCALC_DEBUG
198 MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
199#endif
200 for ( unsigned int i = 0; i < size(); ++i ) {
201 HashType iHash(i);
202 IdType id = getIdentifier( iHash );
203 unsigned int hash = getHash( id );
204 if ( hash != i ) {
205#ifndef IDENTIFIERHASHCALC_DEBUG
206 MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
207#endif
208 log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() getIdentifier(" << i << ")=0x" << std::hex << id << std::dec << " whereas getHash(" << std::hex << id << std::dec << ")=" << hash<<endmsg;
209 ++nErrors;
210 } else {
211#ifdef IDENTIFIERHASHCALC_DEBUG
212 log<<MSG::DEBUG<<"hash=" << i << " <--> id=0x" << std::hex << id << std::dec << ": OK"<<endmsg;
213#endif
214 }
215 }
216#ifdef IDENTIFIERHASHCALC_DEBUG
217 if ( nErrors ) {
218 log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() table contains " << nErrors << " errors." << endmsg;
219 } else {
220 log<<MSG::DEBUG<<"IdentifierHashCalc<T>::checkValidity(): table OK"<<endmsg;
221 }
222#endif
223
224 if ( nErrors ) return false;
225
226 // if we get here, everything is OK!
227 return true;
228}
229
230template <class T>
231void IdentifierHashCalc<T>::dump( std::ostream& os ) const {
232 unsigned int n = size();
233 for ( unsigned int i = 0; i < n; ++i ) {
234 HashType iHash(i);
235 IdType id = getIdentifier( iHash );
236 m_idFields.setAll( id );
237 os << "ID=0x" << std::hex << id << std::dec << " fields=(";
238 for ( int j = NFIELDS-1; j >= 0; --j ) {
239 os << m_idFields[j];
240 if ( j != 0 ) os << ",";
241 }
242 os << ") hash=" << i << "\n";
243 }
244 os << "IdentifierHashTable has " << n << " entries.\n";
245 os << "\nSummary:\n";
246 os << "field min max size factor\n";
247 for ( unsigned int i = 0; i < NFIELDS; ++i ) {
248 os << std::setw(5) << i << " "
249 << std::setw(3) << m_fieldsMin[i] << " "
250 << std::setw(3) << m_fieldsMax[i] << " "
251 << std::setw(4) << m_fieldsSize[i] << " "
252 << std::setw(6) << m_fieldsFactor[i] << "\n";
253 }
254 os.flush();
255}
256
257template <class T>
258inline std::string IdentifierHashCalc<T>::dumpToString() const {
259 std::ostringstream oss;
260 dump( oss );
261 return oss.str();
262}
263
264
265
266
267#endif // MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
#define endmsg
void clear()
Clear the hashtable.
void dump(std::ostream &os=std::cout) const
Dump complete table to output stream.
IdType getIdentifier(const HashType &idHash) const
Get identifier from hash.
T IdFieldsType
define the type IdFieldsType
bool isInRange(const T &idFields) const
T::IdentifierType IdType
define the type IdType
T::HashType HashType
define the type HashType
void setFieldLimits(unsigned int fieldIndex, int fieldMin, int fieldMax)
Set the limits of a specific field.
bool addEntry(const IdType &id)
Add an identifier to the table.
unsigned int size() const
Number of hashes in the table.
HashType getHash(const IdType &id) const
Get hash from 0 to size()-1.
IdentifierHashCalc(const T &idFields)
Make empty table with pointer set to external idHelper, which will be transmitted to the constructor ...
bool checkValidity() const
Check that the table is internally consistent.
std::string dumpToString() const
Dump complete table into a string.
IdentifierHashCalc()
Default constructor makes empty hash table.
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
std::size_t getHash(const T &obj)
Definition hash.h:13
-event-from-file