ATLAS Offline Software
StringPool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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  if (it != m_keymap.end()) {
142  std::cout << std::hex << std::setw(18) << k << " "
143  << std::dec << std::setw(9) << it->second.first << " "
144  << it->second.second << "\n";
145  }
146  }
147 }
148 
149 
158 {
159  bool allgood = true;
160  for (const keymap_t::value_type& p : other.m_keymap) {
161  if (!registerKey (p.first, p.second.second, p.second.first)) {
162  allgood = false;
163  }
164  }
165  return allgood;
166 }
167 
168 
169 //***************************************************************************
170 // StringPool class.
171 //
172 
177  : m_impl (std::make_unique<StringPoolImpl>())
178 {
179 }
180 
181 
187  : m_impl (std::make_unique<StringPoolImpl> (*other.m_impl))
188 {
189 }
190 
191 
197  : m_impl (std::move (other.m_impl))
198 {
199  // False positive:
200  // cppcheck-suppress useInitializationList
201  other.m_impl = std::make_unique<StringPoolImpl>();
202 }
203 
204 
210 {
211  if (this != &other) {
212  *m_impl = *other.m_impl;
213  }
214  return *this;
215 }
216 
217 
223 {
224  if (this != &other) {
225  StringPoolImpl& other_impl = *other.m_impl;
226  *m_impl = std::move (other_impl);
227  }
228  return *this;
229 }
230 
231 
236 {
237  clear();
238 }
239 
240 
251  sgaux_t aux /*= 0*/)
252 {
253  uint64_t crc = CxxUtils::crc64 (str);
254  if (aux) crc = CxxUtils::crc64addint (crc, aux);
255  sgkey_t key = (crc & sgkey_t_max);
256  if (m_impl->registerKey (key, str, aux)) {
257  return key;
258  }
259 
260  // Hash collision...
261  // If we have a transient key, then adjust the hash to avoid a collision.
262  if (SG::isTransientKey (str)) {
263  sgkey_t new_key = ( (key+1) & sgkey_t_max);
264  while (!m_impl->registerKey (new_key, str, aux)) {
265  new_key = ( (new_key+1) & sgkey_t_max);
266  if (key == new_key) std::abort();
267  }
268  return new_key;
269  }
270 
271  // Otherwise raise an exception.
272  sgaux_t old_aux = 0;
273  const std::string* old_str = keyToString (key, old_aux);
274  if (!old_str) std::abort(); // Shouldn't happen.
275  throw ExcSgkeyCollision (str, aux,
276  *old_str, old_aux,
277  key);
278 }
279 
280 
288 const std::string* StringPool::keyToString (sgkey_t key) const
289 {
290  sgaux_t aux;
291  return m_impl->keyToString (key, aux);
292 }
293 
294 
303 const std::string* StringPool::keyToString (sgkey_t key,
304  sgaux_t& aux) const
305 {
306  return m_impl->keyToString (key, aux);
307 }
308 
309 
322  const std::string& str,
323  sgaux_t aux /*= 0*/)
324 {
325  // Make sure the primary mapping is registered first.
326  stringToKey (str, aux);
327  return m_impl->registerKey (key, str, aux);
328 }
329 
330 
334 size_t StringPool::size() const
335 {
336  return m_impl->size();
337 }
338 
339 
343 void StringPool::dump () const
344 {
345  m_impl->dump();
346 }
347 
348 
353 {
354  m_impl->clear();
355 }
356 
357 
366 {
367  return m_impl->merge (*other.m_impl);
368 }
369 
370 
371 } // 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:176
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:407
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:352
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
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:334
SG::StringPoolImpl::dump
void dump() const
Debugging dump. Write to stdout.
Definition: StringPool.cxx:132
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::StringPoolImpl::merge
bool merge(const StringPoolImpl &other)
Merge other pool into this one.
Definition: StringPool.cxx:157
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
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:105
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:288
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:343
SG::StringPool::~StringPool
~StringPool()
Destructor.
Definition: StringPool.cxx:235
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
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:365
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801
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:250
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:321
SG::StringPool::operator=
StringPool & operator=(const StringPool &other)
Assignment/move operators.
Definition: StringPool.cxx:209
fitman.k
k
Definition: fitman.py:528
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37