ATLAS Offline Software
Loading...
Searching...
No Matches
StringPool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
10
11
12#include "SGTools/StringPool.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 <print>
22
23
24namespace SG {
25
26
27//***************************************************************************
28// Implementation class.
29//
30
31
33{
34public:
36 bool registerKey (StringPool::sgkey_t key,
37 const std::string& str,
38 StringPool::sgaux_t aux);
39
41 const std::string* keyToString (StringPool::sgkey_t key,
42 StringPool::sgaux_t& aux) const;
43
45 size_t size() const;
46
48 void clear();
49
51 void dump() const;
52
54 bool merge (const StringPoolImpl& other);
55
56private:
57 // The key hash table.
58 typedef std::pair<StringPool::sgaux_t, std::string> pair_t;
61};
62
63
72bool StringPoolImpl::registerKey (StringPool::sgkey_t key,
73 const std::string& str,
74 StringPool::sgaux_t aux)
75{
76 StringPoolImpl::keymap_t::iterator i = m_keymap.find (key);
77 if (i == m_keymap.end()) {
78 pair_t& p = m_keymap[key];
79 p.first = aux;
80 p.second = str;
81 }
82 else if (i->second.first != aux || i->second.second != str) {
83 return false;
84 }
85 return true;
86}
87
88
97const std::string*
98StringPoolImpl::keyToString (StringPool::sgkey_t key,
99 StringPool::sgaux_t& aux) const
100{
101 StringPoolImpl::keymap_t::const_iterator i = m_keymap.find (key);
102 if (i != m_keymap.end()) {
103 aux = i->second.first;
104 return &i->second.second;
105 }
106 return 0;
107}
108
109
114{
115 return m_keymap.size();
116}
117
118
123{
124 keymap_t().swap (m_keymap);
125}
126
127
132{
133 std::vector<StringPool::sgkey_t> keys;
134 keys.reserve (m_keymap.size());
135 for (const keymap_t::value_type& p : m_keymap)
136 keys.push_back (p.first);
137 std::sort (keys.begin(), keys.end());
138 for (StringPool::sgkey_t k : keys) {
139 keymap_t::const_iterator it = m_keymap.find (k);
140 if (it != m_keymap.end()) {
141 std::println ("{:18x} {:9} {}", k, it->second.first, it->second.second);
142 }
143 }
144}
145
146
155{
156 bool allgood = true;
157 for (const keymap_t::value_type& p : other.m_keymap) {
158 if (!registerKey (p.first, p.second.second, p.second.first)) {
159 allgood = false;
160 }
161 }
162 return allgood;
163}
164
165
166//***************************************************************************
167// StringPool class.
168//
169
173StringPool::StringPool()
174 : m_impl (std::make_unique<StringPoolImpl>())
175{
176}
177
178
183StringPool::StringPool (const StringPool& other)
184 : m_impl (std::make_unique<StringPoolImpl> (*other.m_impl))
185{
186}
187
188
193StringPool::StringPool (StringPool&& other)
194 : m_impl (std::move (other.m_impl))
195{
196 // False positive:
197 // cppcheck-suppress useInitializationList
198 other.m_impl = std::make_unique<StringPoolImpl>();
199}
200
201
206StringPool& StringPool::operator= (const StringPool& other)
207{
208 if (this != &other) {
209 *m_impl = *other.m_impl;
210 }
211 return *this;
212}
213
214
219StringPool& StringPool::operator= (StringPool&& other)
220{
221 if (this != &other) {
222 StringPoolImpl& other_impl = *other.m_impl;
223 *m_impl = std::move (other_impl);
224 }
225 return *this;
226}
227
228
232StringPool::~StringPool()
233{
234 clear();
235}
236
237
247StringPool::sgkey_t StringPool::stringToKey (const std::string& str,
248 sgaux_t aux /*= 0*/)
249{
250 uint64_t crc = CxxUtils::crc64 (str);
251 if (aux) crc = CxxUtils::crc64addint (crc, aux);
252 sgkey_t key = (crc & sgkey_t_max);
253 if (m_impl->registerKey (key, str, aux)) {
254 return key;
255 }
256
257 // Hash collision...
258 // If we have a transient key, then adjust the hash to avoid a collision.
259 if (SG::isTransientKey (str)) {
260 sgkey_t new_key = ( (key+1) & sgkey_t_max);
261 while (!m_impl->registerKey (new_key, str, aux)) {
262 new_key = ( (new_key+1) & sgkey_t_max);
263 if (key == new_key) std::abort();
264 }
265 return new_key;
266 }
267
268 // Otherwise raise an exception.
269 sgaux_t old_aux = 0;
270 const std::string* old_str = keyToString (key, old_aux);
271 if (!old_str) std::abort(); // Shouldn't happen.
272 throw ExcSgkeyCollision (str, aux,
273 *old_str, old_aux,
274 key);
275}
276
277
285const std::string* StringPool::keyToString (sgkey_t key) const
286{
287 sgaux_t aux;
288 return m_impl->keyToString (key, aux);
289}
290
291
300const std::string* StringPool::keyToString (sgkey_t key,
301 sgaux_t& aux) const
302{
303 return m_impl->keyToString (key, aux);
304}
305
306
318bool StringPool::registerKey (sgkey_t key,
319 const std::string& str,
320 sgaux_t aux /*= 0*/)
321{
322 // Make sure the primary mapping is registered first.
323 stringToKey (str, aux);
324 return m_impl->registerKey (key, str, aux);
325}
326
327
331size_t StringPool::size() const
332{
333 return m_impl->size();
334}
335
336
340void StringPool::dump () const
341{
342 m_impl->dump();
343}
344
345
349void StringPool::clear()
350{
351 m_impl->clear();
352}
353
354
362bool StringPool::merge (const StringPool& other)
363{
364 return m_impl->merge (*other.m_impl);
365}
366
367
368} // namespace SG
Exceptions that can be thrown by SGTools.
Maintain a mapping of strings to 64-bit ints.
std::unique_ptr< StringPoolImpl > m_impl
Definition StringPool.h:137
const std::string * keyToString(sgkey_t key) const
Find the string corresponding to a given key.
sgkey_t stringToKey(const std::string &str, sgaux_t aux=0)
void clear()
Empty the pool.
Exception — sgkey hash collision.
bool merge(const StringPoolImpl &other)
Merge other pool into this one.
void clear()
Clear data.
size_t size() const
Number of registered mappings.
std::pair< StringPool::sgaux_t, std::string > pair_t
SG::SGKeyMap< pair_t > keymap_t
void dump() const
Debugging dump. Write to stdout.
const std::string * keyToString(StringPool::sgkey_t key, StringPool::sgaux_t &aux) const
Find the string corresponding to a given key.
bool registerKey(StringPool::sgkey_t key, const std::string &str, StringPool::sgaux_t aux)
Remember an additional mapping from key to string.
A crc-64 implementation, using pclmul where possible.
uint64_t crc64(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string,.
Definition crc64.cxx:695
uint64_t crc64addint(uint64_t crc, uint64_t x)
Extend a previously-calculated CRC to include an int.
Definition crc64.cxx:731
Forward declaration.
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
std::unordered_map< sgkey_t, T > SGKeyMap
A map using sgkey_t as a key.
Definition sgkey_t.h:93
Definition merge.py:1
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.