ATLAS Offline Software
StringPool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
12 #include "SGTools/StringPool.h"
13 #include "SGTools/transientKey.h"
14 #include "SGTools/exceptions.h"
15 #include "CxxUtils/crc64.h"
16 #include <map>
17 #include <unordered_map>
18 #include <vector>
19 #include <algorithm>
20 #include <cstdlib>
21 #include <iostream>
22 #include <iomanip>
23 
24 
25 namespace SG {
26 
27 
28 //***************************************************************************
29 // Implementation class.
30 //
31 
32 
34 {
35 public:
38  const std::string& str,
40 
42  const std::string* keyToString (StringPool::sgkey_t key,
43  StringPool::sgaux_t& aux) const;
44 
46  size_t size() const;
47 
49  void clear();
50 
52  void dump() const;
53 
55  bool merge (const StringPoolImpl& other);
56 
57 private:
58  // The key hash table.
59  typedef std::pair<StringPool::sgaux_t, std::string> pair_t;
62 };
63 
64 
74  const std::string& str,
76 {
78  if (i == m_keymap.end()) {
79  pair_t& p = m_keymap[key];
80  p.first = aux;
81  p.second = str;
82  }
83  else if (i->second.first != aux || i->second.second != str) {
84  return false;
85  }
86  return true;
87 }
88 
89 
98 const std::string*
100  StringPool::sgaux_t& aux) const
101 {
102  StringPoolImpl::keymap_t::const_iterator i = m_keymap.find (key);
103  if (i != m_keymap.end()) {
104  aux = i->second.first;
105  return &i->second.second;
106  }
107  return 0;
108 }
109 
110 
114 size_t StringPoolImpl::size() const
115 {
116  return m_keymap.size();
117 }
118 
119 
124 {
125  keymap_t().swap (m_keymap);
126 }
127 
128 
133 {
134  std::vector<StringPool::sgkey_t> keys;
135  keys.reserve (m_keymap.size());
136  for (const keymap_t::value_type& p : m_keymap)
137  keys.push_back (p.first);
138  std::sort (keys.begin(), keys.end());
139  for (StringPool::sgkey_t k : keys) {
140  keymap_t::const_iterator it = m_keymap.find (k);
141  std::cout << std::hex << std::setw(18) << k << " "
142  << std::dec << std::setw(9) << it->second.first << " "
143  << it->second.second << "\n";
144  }
145 }
146 
147 
156 {
157  bool allgood = true;
158  for (const keymap_t::value_type& p : other.m_keymap) {
159  if (!registerKey (p.first, p.second.second, p.second.first)) {
160  allgood = false;
161  }
162  }
163  return allgood;
164 }
165 
166 
167 //***************************************************************************
168 // StringPool class.
169 //
170 
175  : m_impl (std::make_unique<StringPoolImpl>())
176 {
177 }
178 
179 
185  : m_impl (std::make_unique<StringPoolImpl> (*other.m_impl))
186 {
187 }
188 
189 
195  : m_impl (std::move (other.m_impl))
196 {
197  // False positive:
198  // cppcheck-suppress useInitializationList
199  other.m_impl = std::make_unique<StringPoolImpl>();
200 }
201 
202 
208 {
209  if (this != &other) {
210  *m_impl = *other.m_impl;
211  }
212  return *this;
213 }
214 
215 
221 {
222  if (this != &other) {
223  StringPoolImpl& other_impl = *other.m_impl;
224  *m_impl = std::move (other_impl);
225  }
226  return *this;
227 }
228 
229 
234 {
235  clear();
236 }
237 
238 
249  sgaux_t aux /*= 0*/)
250 {
251  uint64_t crc = CxxUtils::crc64 (str);
252  if (aux) crc = CxxUtils::crc64addint (crc, aux);
253  sgkey_t key = (crc & sgkey_t_max);
254  if (m_impl->registerKey (key, str, aux)) {
255  return key;
256  }
257 
258  // Hash collision...
259  // If we have a transient key, then adjust the hash to avoid a collision.
260  if (SG::isTransientKey (str)) {
261  sgkey_t new_key = ( (key+1) & sgkey_t_max);
262  while (!m_impl->registerKey (new_key, str, aux)) {
263  new_key = ( (new_key+1) & sgkey_t_max);
264  if (key == new_key) std::abort();
265  }
266  return new_key;
267  }
268 
269  // Otherwise raise an exception.
270  sgaux_t old_aux = 0;
271  const std::string* old_str = keyToString (key, old_aux);
272  if (!old_str) std::abort(); // Shouldn't happen.
273  throw ExcSgkeyCollision (str, aux,
274  *old_str, old_aux,
275  key);
276 }
277 
278 
286 const std::string* StringPool::keyToString (sgkey_t key) const
287 {
288  sgaux_t aux;
289  return m_impl->keyToString (key, aux);
290 }
291 
292 
301 const std::string* StringPool::keyToString (sgkey_t key,
302  sgaux_t& aux) const
303 {
304  return m_impl->keyToString (key, aux);
305 }
306 
307 
320  const std::string& str,
321  sgaux_t aux /*= 0*/)
322 {
323  // Make sure the primary mapping is registered first.
324  stringToKey (str, aux);
325  return m_impl->registerKey (key, str, aux);
326 }
327 
328 
332 size_t StringPool::size() const
333 {
334  return m_impl->size();
335 }
336 
337 
341 void StringPool::dump () const
342 {
343  m_impl->dump();
344 }
345 
346 
351 {
352  m_impl->clear();
353 }
354 
355 
364 {
365  return m_impl->merge (*other.m_impl);
366 }
367 
368 
369 } // namespace SG
SG::StringPoolImpl::size
size_t size() const
Number of registered mappings.
Definition: StringPool.cxx:114
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
exceptions.h
Exceptions that can be thrown by SGTools.
SG::StringPool::StringPool
StringPool()
Constructor.
Definition: StringPool.cxx:174
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::isTransientKey
bool isTransientKey(const std::string &key)
Test to see if a key is transoent.
Definition: transientKey.h:41
SG::StringPool
Definition: StringPool.h:35
SG::StringPool::m_impl
std::unique_ptr< StringPoolImpl > m_impl
Definition: StringPool.h:137
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
SG::StringPoolImpl
Definition: StringPool.cxx:34
SG::StringPoolImpl::clear
void clear()
Clear data.
Definition: StringPool.cxx:123
skel.it
it
Definition: skel.GENtoEVGEN.py:423
SG::StringPoolImpl::pair_t
std::pair< StringPool::sgaux_t, std::string > pair_t
Definition: StringPool.cxx:59
transientKey.h
SG::StringPool::clear
void clear()
Empty the pool.
Definition: StringPool.cxx:350
SG::StringPool::sgkey_t_max
static const sgkey_t sgkey_t_max
Definition: StringPool.h:46
SG::StringPool::size
size_t size() const
Number of registered mappings.
Definition: StringPool.cxx:332
SG::StringPoolImpl::dump
void dump() const
Debugging dump. Write to stdout.
Definition: StringPool.cxx:132
lumiFormat.i
int i
Definition: lumiFormat.py:92
SG::StringPoolImpl::merge
bool merge(const StringPoolImpl &other)
Merge other pool into this one.
Definition: StringPool.cxx:155
StringPool.h
Maintain a mapping of strings to 64-bit ints.
CxxUtils::crc64addint
uint64_t crc64addint(uint64_t crc, uint64_t x)
Extend a previously-calculated CRC to include an int.
Definition: crc64.cxx:732
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
SG::ExcSgkeyCollision
Exception — sgkey hash collision.
Definition: Control/SGTools/SGTools/exceptions.h:102
SG::StringPool::sgaux_t
unsigned int sgaux_t
Type of auxiliary data.
Definition: StringPool.h:41
SG::StringPool::sgkey_t
uint32_t sgkey_t
Type of the integer keys.
Definition: StringPool.h:38
SG::StringPool::keyToString
const std::string * keyToString(sgkey_t key) const
Find the string corresponding to a given key.
Definition: StringPool.cxx:286
CxxUtils::crc64
uint64_t crc64(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string,.
Definition: crc64.cxx:696
SG::StringPoolImpl::keyToString
const std::string * keyToString(StringPool::sgkey_t key, StringPool::sgaux_t &aux) const
Find the string corresponding to a given key.
Definition: StringPool.cxx:99
SG::StringPoolImpl::registerKey
bool registerKey(StringPool::sgkey_t key, const std::string &str, StringPool::sgaux_t aux)
Remember an additional mapping from key to string.
Definition: StringPool.cxx:73
SG::StringPool::dump
void dump() const
Debugging dump.
Definition: StringPool.cxx:341
SG::StringPool::~StringPool
~StringPool()
Destructor.
Definition: StringPool.cxx:233
SG::StringPoolImpl::keymap_t
SG::SGKeyMap< pair_t > keymap_t
Definition: StringPool.cxx:60
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
SG::StringPoolImpl::m_keymap
keymap_t m_keymap
Definition: StringPool.cxx:61
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
SG::SGKeyMap
std::unordered_map< sgkey_t, T > SGKeyMap
A map using sgkey_t as a key.
Definition: CxxUtils/CxxUtils/sgkey_t.h:93
SG::StringPool::merge
bool merge(const StringPool &other)
Merge another pool into this one.
Definition: StringPool.cxx:363
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:790
crc64.h
A crc-64 implementation, using pclmul where possible.
SG::StringPool::stringToKey
sgkey_t stringToKey(const std::string &str, sgaux_t aux=0)
Find the key for a string.
Definition: StringPool.cxx:248
SG::StringPool::registerKey
bool registerKey(sgkey_t key, const std::string &str, sgaux_t aux=0)
Remember an additional mapping from key to string.
Definition: StringPool.cxx:319
SG::StringPool::operator=
StringPool & operator=(const StringPool &other)
Assignment/move operators.
Definition: StringPool.cxx:207
fitman.k
k
Definition: fitman.py:528
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37