ATLAS Offline Software
Loading...
Searching...
No Matches
StringPool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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 <iostream>
22#include <iomanip>
23
24
25namespace SG {
26
27
28//***************************************************************************
29// Implementation class.
30//
31
32
34{
35public:
38 const std::string& str,
40
42 const std::string* keyToString (StringPool::sgkey_t key,
44
46 size_t size() const;
47
49 void clear();
50
52 void dump() const;
53
55 bool merge (const StringPoolImpl& other);
56
57private:
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{
77 StringPoolImpl::keymap_t::iterator i = m_keymap.find (key);
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
98const std::string*
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
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
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
288const std::string* StringPool::keyToString (sgkey_t key) const
289{
290 sgaux_t aux;
291 return m_impl->keyToString (key, aux);
292}
293
294
303const 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.
327 return m_impl->registerKey (key, str, aux);
328}
329
330
334size_t StringPool::size() const
335{
336 return m_impl->size();
337}
338
339
343void StringPool::dump () const
344{
345 m_impl->dump();
346}
347
348
353{
354 m_impl->clear();
355}
356
357
365bool StringPool::merge (const StringPool& other)
366{
367 return m_impl->merge (*other.m_impl);
368}
369
370
371} // namespace SG
Exceptions that can be thrown by SGTools.
Maintain a mapping of strings to 64-bit ints.
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.
unsigned int sgaux_t
Type of auxiliary data.
Definition StringPool.h:41
bool registerKey(sgkey_t key, const std::string &str, sgaux_t aux=0)
Remember an additional mapping from key to string.
std::unique_ptr< StringPoolImpl > m_impl
Definition StringPool.h:137
void dump() const
Debugging dump.
const std::string * keyToString(sgkey_t key) const
Find the string corresponding to a given key.
StringPool()
Constructor.
static const sgkey_t sgkey_t_max
Definition StringPool.h:46
~StringPool()
Destructor.
size_t size() const
Number of registered mappings.
bool merge(const StringPool &other)
Merge another pool into this one.
sgkey_t stringToKey(const std::string &str, sgaux_t aux=0)
Find the key for a string.
uint32_t sgkey_t
Type of the integer keys.
Definition StringPool.h:38
StringPool & operator=(const StringPool &other)
Assignment/move operators.
void clear()
Empty the pool.
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:696
uint64_t crc64addint(uint64_t crc, uint64_t x)
Extend a previously-calculated CRC to include an int.
Definition crc64.cxx:732
Forward declaration.
std::unordered_map< sgkey_t, T > SGKeyMap
A map using sgkey_t as a key.
Definition sgkey_t.h:93
bool isTransientKey(const std::string &key)
Test to see if a key is transoent.
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.