ATLAS Offline Software
Loading...
Searching...
No Matches
Token.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cstdio>
8#include <cstring>
9#include <climits>
10#include <atomic>
11#include <format>
12#include <charconv>
13#include <string_view>
14#include "CxxUtils/HexString.h"
15
16constexpr std::string_view LABEL_DB = "[DB=";
17constexpr std::string_view LABEL_CNT = "[CNT=";
18constexpr std::string_view LABEL_CLID = "[CLID=";
19constexpr std::string_view LABEL_TECH = "[TECH=";
20constexpr std::string_view LABEL_OID = "[OID=";
21
22static const int KEY_MASK = (~0u) << CHAR_BIT;
23static std::atomic<int> s_numCount { 0 };
24
26
29 m_technology(0),
30 m_dbID(Guid::null()),
31 m_classID(Guid::null()),
32 m_oid(OID_t(~0x0LL, ~0x0LL)),
33 m_type(0) {
34 s_numCount.fetch_add(1, std::memory_order_relaxed);
35}
36
38Token::Token(const Token& copy) : m_refCount(1),
40 m_dbID(copy.m_dbID),
41 m_classID(copy.m_classID),
42 m_oid(copy.m_oid),
43 m_type(0) {
44 copy.setData(this);
45 s_numCount.fetch_add(1, std::memory_order_relaxed);
46}
47
49Token::Token(const Token* source) : m_refCount(1),
50 m_technology(0),
51 m_dbID(Guid::null()),
52 m_classID(Guid::null()),
53 m_oid(OID_t(~0x0LL, ~0x0LL)),
54 m_type(0) {
55 if (source != 0) {
56 source->setData(this);
57 }
58 s_numCount.fetch_add(1, std::memory_order_relaxed);
59}
60
62Token::Token(Token&& source) noexcept
63 : m_refCount (1),
64 m_technology (source.m_technology),
65 m_dbID (std::move (source.m_dbID)),
66 m_cntID (std::move (source.m_cntID)),
67 m_classID (std::move (source.m_classID)),
68 m_oid (std::move (source.m_oid)),
69 m_type (source.m_type),
70 m_auxString (std::move (source.m_auxString))
71{
72 s_numCount.fetch_add(1, std::memory_order_relaxed);
73}
74
75
77 s_numCount.fetch_sub(1, std::memory_order_relaxed);
78}
79
82 int cnt = --m_refCount;
83 if (0 >= cnt) {
84 delete this;
85 }
86 return cnt;
87}
88
91 if (&copy != this) {
92 copy.setData(this);
93 }
94 return *this;
95}
96
98bool Token::equal(const Token& copy) const {
99 if (&copy != this) {
100 if (m_oid.second == copy.m_oid.second) {
101 if (m_classID == copy.m_classID) {
102 if (m_dbID == copy.m_dbID) {
103 if (m_cntID == copy.m_cntID) {
104 return true;
105 }
106 }
107 }
108 }
109 return false;
110 }
111 return true;
112}
113
115bool Token::less(const Token& copy) const {
116 if (&copy != this) {
117 if (m_oid.second < copy.m_oid.second)
118 return true;
119 else if (m_oid.second > copy.m_oid.second)
120 return false;
121 if (!(m_classID == copy.m_classID)) {
122 return (m_classID < copy.m_classID);
123 }
124 if (!(m_dbID == copy.m_dbID)) {
125 return (m_dbID < copy.m_dbID);
126 }
127 int res = m_cntID.compare(copy.m_cntID);
128 if (res != 0) {
129 return (res < 0);
130 }
131 }
132 return false;
133}
134
135const std::string Token::toString() const {
136// Pre-compute the hex representations using the format strings
137 CxxUtils::HexString<"[TECH={}]"> techHex(m_technology);
138 CxxUtils::HexString<"[OID={}-"> oid1Hex(static_cast<uint64_t>(m_oid.first));
139 CxxUtils::HexString<"{}]"> oid2Hex(static_cast<uint64_t>(m_oid.second));
140
141 std::string res;
142 // Reserve exact capacity to prevent reallocations.
143 // "[DB=" (4) + Guid (36) + "][CNT=" (6) + CNT + "][CLID=" (7) + Guid (36) + "]" (1)
144 res.reserve(4 + 36 + 6 + m_cntID.size() + 7 + 36 + 1 +
145 techHex.size() + oid1Hex.size() + oid2Hex.size() + m_auxString.size());
146
147 res += "[DB=";
148 size_t pos = res.size();
149 res.resize(pos + 36);
150 m_dbID.toString(std::span<char, 36>(res.data() + pos, 36));
151
152 res += "][CNT=";
153 res += m_cntID;
154
155 res += "][CLID=";
156 pos = res.size();
157 res.resize(pos + 36);
158 m_classID.toString(std::span<char, 36>(res.data() + pos, 36));
159 res += ']';
160
161 res += static_cast<std::string_view>(techHex);
162 res += static_cast<std::string_view>(oid1Hex);
163 res += static_cast<std::string_view>(oid2Hex);
164 res += m_auxString;
165
166 return res;
167}
168
169Token& Token::fromString(const std::string_view src) {
170 m_auxString.clear();
171 size_t pos = 0;
172 while (pos < src.size()) {
173 size_t start = src.find('[', pos);
174 if (start == std::string_view::npos) break;
175 size_t eq = src.find('=', start);
176 size_t end = src.find(']', start);
177 if (eq != std::string_view::npos && end != std::string_view::npos) {
178 std::string_view label = src.substr(start, eq - start + 1);
179 if (label == LABEL_DB) {
180 m_dbID.fromString(src.substr(eq + 1, end - eq - 1));
181 } else if (label == LABEL_CNT) {
182 m_cntID = std::string(src.substr(eq + 1, end - eq - 1));
183 } else if (label == LABEL_CLID) {
184 m_classID.fromString(src.substr(eq + 1, end - eq - 1));
185 } else if (label == LABEL_TECH) {
186 std::string_view num_str = src.substr(eq + 1, end - eq - 1);
187 int tech = 0;
188 std::from_chars(num_str.data(), num_str.data() + num_str.size(), tech, 16);
189 m_technology = tech;
190 } else if (label == LABEL_OID) {
191 std::string_view oid_str = src.substr(eq + 1, end - eq - 1);
192 size_t dash = oid_str.find('-');
193 if (dash != std::string_view::npos) {
194 std::string_view first_str = oid_str.substr(0, dash);
195 std::string_view second_str = oid_str.substr(dash + 1);
196
197 // Check if this is legacy format (8 digits) vs modern format (16 digits)
198 // Legacy format: 5 + 8 + 1 + 8 + 1 = 23 characters total for [OID=XXXXXXXX-XXXXXXXX]
199 // Modern format: 5 + 16 + 1 + 16 + 1 = 39 characters total for [OID=XXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXX]
200 bool is_legacy = (end - start + 1) == 23; // Total bracket length check
201
202 uint64_t first = 0;
203 uint64_t second = 0;
204 std::from_chars(first_str.data(), first_str.data() + first_str.size(), first, 16);
205 std::from_chars(second_str.data(), second_str.data() + second_str.size(), second, 16);
206
207 if (is_legacy) {
208 // Handle legacy format: extend 32-bit ~0x0 to 64-bit ~0x0LL
209 if (static_cast<uint32_t>(first) == ~0x0U) first = ~0x0ULL;
210 if (static_cast<uint32_t>(second) == ~0x0U) second = ~0x0ULL;
211 }
212
213 m_oid.first = static_cast<long long int>(first);
214 m_oid.second = static_cast<long long int>(second);
215 }
216 } else {
217 m_auxString += src.substr(start, end - start + 1);
218 }
219 pos = end + 1;
220 } else {
221 break;
222 }
223 }
224 return *this;
225}
226
228const std::string Token::key() const {
229 //Do not replace with std::format unless it is found to be more performant
230 // m_technology & KEY_MASK yields an unsigned int -> 8 hex digits
231 CxxUtils::HexString<"[TECH={}]"> techHex(m_technology & KEY_MASK);
232
233 std::string res;
234 // "[DB=" (4) + Guid (36) + "][CNT=" (6) + CNT + "][CLID=" (7) + Guid (36) + "]" (1)
235 res.reserve(4 + 36 + 6 + m_cntID.size() + 7 + 36 + 1 + techHex.size());
236
237 res += "[DB=";
238 size_t pos = res.size();
239 res.resize(pos + 36);
240 m_dbID.toString(std::span<char, 36>(res.data() + pos, 36));
241
242 res += "][CNT=";
243 res += m_cntID;
244
245 res += "][CLID=";
246 pos = res.size();
247 res.resize(pos + 36);
248 m_classID.toString(std::span<char, 36>(res.data() + pos, 36));
249 res += ']';
250
251 res += static_cast<std::string_view>(techHex);
252
253 return res;
254}
255
256const Token& Token::set(Token* pToken) const {
257 pToken->m_technology = m_technology;
258 pToken->m_dbID = m_dbID;
259 pToken->m_cntID = m_cntID;
260 pToken->m_classID = m_classID;
261 pToken->m_oid.first = m_oid.first;
262 return *this;
263}
264
265const Token& Token::setData(Token* pToken) const {
266 this->set(pToken);
267 pToken->m_oid.second = m_oid.second;
268 pToken->m_type = m_type;
269 pToken->m_auxString = m_auxString;
270 return *this;
271}
Provides a utility class to format integral types as hexadecimal strings at compile time or with VERY...
std::pair< std::vector< unsigned int >, bool > res
constexpr std::string_view LABEL_DB
Definition Token.cxx:16
constexpr std::string_view LABEL_TECH
Definition Token.cxx:19
static std::atomic< int > s_numCount
Definition Token.cxx:23
constexpr std::string_view LABEL_CLID
Definition Token.cxx:18
constexpr std::string_view LABEL_CNT
Definition Token.cxx:17
constexpr std::string_view LABEL_OID
Definition Token.cxx:20
static const int KEY_MASK
Definition Token.cxx:22
This file contains the class definition for the Token class (migrated from POOL).
A class that formats an integer as a hexadecimal string embedded within a format string.
Definition HexString.h:54
constexpr std::size_t size() const noexcept
Returns the total size of the formatted string.
Definition HexString.h:165
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition Guid.h:25
int m_refCount
Reference count.
Definition Token.h:113
const Token & setData(Token *pToken) const
Set all the data part of the token.
Definition Token.cxx:265
virtual ~Token()
Standard destructor: release all allocated resources.
Definition Token.cxx:76
Guid m_classID
Object global identifier.
Definition Token.h:121
unsigned int m_technology
Technology identifier.
Definition Token.h:115
Token(const Token &copy)
No copy allowed: put prototype to disable bit-wise copy.
Definition Token.cxx:38
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition Token.cxx:135
OID_t m_oid
Persistent object identifier.
Definition Token.h:123
virtual bool less(const Token &pTok) const
Fast token comparison: operator less.
Definition Token.cxx:115
virtual bool equal(const Token &pTok) const
Fast token comparison: operator equals.
Definition Token.cxx:98
Token()
Standard Constructor.
Definition Token.cxx:28
int release()
Release token: Decrease reference count and eventually delete.
Definition Token.cxx:81
Token & operator=(const Token &copy)
No assignment allowed: put prototype to disable bit-wise assignment.
Definition Token.cxx:90
static int numInstances()
expose Token instance counter for debugging
Definition Token.cxx:25
std::string m_auxString
Auxiliary string.
Definition Token.h:127
std::string m_cntID
Container identifier.
Definition Token.h:119
virtual const std::string key() const
Retrieve token key.
Definition Token.cxx:228
Token & fromString(const std::string_view from)
Build from the string representation of a token.
Definition Token.cxx:169
int m_type
Token type.
Definition Token.h:125
const Token & set(Token *pToken) const
Set token information.
Definition Token.cxx:256
Guid m_dbID
Database identifier.
Definition Token.h:117
std::string label(const std::string &format, int i)
Definition label.h:19