libbmq b6028b29b733bc7541593d2905a5f79a9f0192fc
Loading...
Searching...
No Matches
bmqt_messageguid.h
Go to the documentation of this file.
1// Copyright 2014-2023 Bloomberg Finance L.P.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16// bmqt_messageguid.h -*-C++-*-
17#ifndef INCLUDED_BMQT_MESSAGEGUID
18#define INCLUDED_BMQT_MESSAGEGUID
19
74
75// BDE
76#include <bsl_cstring.h> // for bsl::memset, bsl::memcmp
77
78#include <bsl_iosfwd.h>
79#include <bsl_type_traits.h>
80#include <bsla_annotations.h>
81#include <bslh_hash.h>
82#include <bslmf_isbitwiseequalitycomparable.h>
83#include <bslmf_istriviallycopyable.h>
84#include <bslmf_nestedtraitdeclaration.h>
85#include <bsls_types.h>
86
87namespace BloombergLP {
88namespace bmqt {
89
90// =================
91// class MessageGUID
92// =================
93
97 // FRIENDS
98 friend bool operator==(const MessageGUID& lhs, const MessageGUID& rhs);
99 friend bool operator!=(const MessageGUID& lhs, const MessageGUID& rhs);
100 friend struct MessageGUIDLess;
101 template <class HASH_ALGORITHM>
102 friend void hashAppend(HASH_ALGORITHM& hashAlgo, const MessageGUID& guid);
103
104 public:
105 // TYPES
106
108 enum Enum {
110 e_SIZE_BINARY = 16
111
115 };
116
117 // TRAITS
118 BSLMF_NESTED_TRAIT_DECLARATION(MessageGUID,
119 bslmf::IsBitwiseEqualityComparable)
120 BSLMF_NESTED_TRAIT_DECLARATION(MessageGUID, bsl::is_trivially_copyable)
121
122 private:
123 // PRIVATE CONSTANTS
124
126 static const char k_UNSET_GUID[e_SIZE_BINARY];
127
128 private:
129 // IMPLEMENTATION NOTE: Some structs in bmqp::Protocol.h blindly
130 // reinterpret_cast a char[e_SIZE_BINARY] to a
131 // MessageGUID (instead of using 'fromBinary()') so
132 // that they can return a const MessageGUID&.
133 // IMPLEMENTATION NOTE: See mqbu_messageguidutil.cpp for internal layout of
134 // MessageGUID
135
136 // DATA
137 char d_buffer[e_SIZE_BINARY];
138
139 public:
140 // CLASS METHODS
141
145 static bool isValidHexRepresentation(const char* buffer);
146
147 // CREATORS
148
151 MessageGUID();
152
154 ~MessageGUID();
155
156 // MANIPULATORS
157
162 MessageGUID& fromBinary(const unsigned char* buffer);
163
169 MessageGUID& fromHex(const char* buffer);
170
171 // ACCESSORS
172
174 bool isUnset() const;
175
180 void toBinary(unsigned char* destination) const;
181
186 void toHex(char* destination) const;
187
200 bsl::ostream&
201 print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const;
202};
203
204// FREE OPERATORS
205
206// -----------------
207// class MessageGUID
208// -----------------
209
215bsl::ostream& operator<<(bsl::ostream& stream, const MessageGUID& rhs);
216
220bool operator==(const MessageGUID& lhs, const MessageGUID& rhs);
221
225bool operator!=(const MessageGUID& lhs, const MessageGUID& rhs);
226
234bool operator<(const MessageGUID& lhs, const MessageGUID& rhs);
235
236// =====================
237// class MessageGUIDLess
238// =====================
239
242 // ACCESSORS
243
246 bool operator()(const MessageGUID& lhs, const MessageGUID& rhs) const;
247};
248
249// =========================
250// class MessageGUIDHashAlgo
251// =========================
252
259 private:
260 // DATA
261 bsls::Types::Uint64 d_result;
262
263 public:
264 // TYPES
265 typedef bsls::Types::Uint64 result_type;
266
267 // CREATORS
268
271
272 // MANIPULATORS
273 void operator()(const void* data, size_t numBytes);
274
277};
278
279// ============================================================================
280// INLINE DEFINITIONS
281// ============================================================================
282
283// -----------------
284// class MessageGUID
285// -----------------
286
287// CREATORS
289{
290 bsl::memcpy(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
291}
292
294{
295#ifdef BSLS_ASSERT_SAFE_IS_ACTIVE
296 bsl::memcpy(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
297#endif
298}
299
300// ACCESSORS
301inline bool MessageGUID::isUnset() const
302{
303 return 0 == bsl::memcmp(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
304}
305
306// FREE FUNCTIONS
307template <class HASH_ALGORITHM>
308void hashAppend(HASH_ALGORITHM& hashAlgo, const MessageGUID& guid)
309{
310 using bslh::hashAppend; // for ADL
311 hashAppend(hashAlgo, guid.d_buffer); // hashes entire buffer array
312}
313
314// ----------------------
315// struct MessageGUIDLess
316// ----------------------
317
319 const MessageGUID& rhs) const
320{
321 return 0 >
322 bsl::memcmp(lhs.d_buffer, rhs.d_buffer, MessageGUID::e_SIZE_BINARY);
323}
324
325// -------------------------
326// class MessageGUIDHashAlgo
327// -------------------------
328
329// CREATORS
331: d_result(0)
332{
333}
334
335// MANIPULATORS
336inline void MessageGUIDHashAlgo::operator()(const void* data,
337 BSLA_UNUSED size_t numBytes)
338{
339 // Implementation note: the implementation is based on Jon Maiga's research
340 // on different bit mixers and their qualities (look for `mxm`):
341 // https://jonkagstrom.com/bit-mixer-construction/index.html
342
343 // Typically, bit mixers are used as the last step of computing more
344 // general hashes. But it's more than enough to use it on its own for
345 // our specific use case here.
346
347 // Performance evaluation, hash quality and avalanche effect are here:
348 // https://github.com/bloomberg/blazingmq/pull/348
349
350 struct LocalFuncs {
352 inline static bsls::Types::Uint64 mix(bsls::Types::Uint64 x)
353 {
354 x *= 0xbf58476d1ce4e5b9ULL;
355 x ^= x >> 56;
356 x *= 0x94d049bb133111ebULL;
357 return x;
358 }
359
361 inline static bsls::Types::Uint64 combine(bsls::Types::Uint64 lhs,
362 bsls::Types::Uint64 rhs)
363 {
364 lhs ^= rhs + 0x517cc1b727220a95 + (lhs << 6) + (lhs >> 2);
365 return lhs;
366 }
367 };
368
369 // `data` buffer might not be aligned to 8 bytes, so recasting the pointer
370 // might lead to UB
371 bsls::Types::Uint64 parts[2];
372 bsl::memcpy(parts, data, bmqt::MessageGUID::e_SIZE_BINARY);
373
374 parts[0] = LocalFuncs::mix(parts[0]);
375 parts[1] = LocalFuncs::mix(parts[1]);
376 d_result = LocalFuncs::combine(parts[0], parts[1]);
377}
378
383
384} // close package namespace
385
386// -----------------
387// class MessageGUID
388// -----------------
389
390// FREE OPERATORS
391inline bool bmqt::operator==(const bmqt::MessageGUID& lhs,
392 const bmqt::MessageGUID& rhs)
393{
394 return 0 ==
395 bsl::memcmp(lhs.d_buffer, rhs.d_buffer, MessageGUID::e_SIZE_BINARY);
396}
397
398inline bool bmqt::operator!=(const bmqt::MessageGUID& lhs,
399 const bmqt::MessageGUID& rhs)
400{
401 return !(lhs == rhs);
402}
403
404inline bool bmqt::operator<(const bmqt::MessageGUID& lhs,
405 const bmqt::MessageGUID& rhs)
406{
407 MessageGUIDLess less;
408 return less(lhs, rhs);
409}
410
411inline bsl::ostream& bmqt::operator<<(bsl::ostream& stream,
412 const bmqt::MessageGUID& rhs)
413{
414 return rhs.print(stream, 0, -1);
415}
416
417} // close enterprise namespace
418
419#endif
Definition bmqt_messageguid.h:258
MessageGUIDHashAlgo()
Constructor.
Definition bmqt_messageguid.h:330
void operator()(const void *data, size_t numBytes)
Definition bmqt_messageguid.h:336
result_type computeHash()
Compute and return the hash for the GUID.
Definition bmqt_messageguid.h:379
bsls::Types::Uint64 result_type
Definition bmqt_messageguid.h:265
Definition bmqt_messageguid.h:96
MessageGUID & fromHex(const char *buffer)
friend bool operator!=(const MessageGUID &lhs, const MessageGUID &rhs)
MessageGUID()
Definition bmqt_messageguid.h:288
bool isUnset() const
Return true if the value of this object is not set.
Definition bmqt_messageguid.h:301
~MessageGUID()
Destructor.
Definition bmqt_messageguid.h:293
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
friend void hashAppend(HASH_ALGORITHM &hashAlgo, const MessageGUID &guid)
Definition bmqt_messageguid.h:308
static bool isValidHexRepresentation(const char *buffer)
friend bool operator==(const MessageGUID &lhs, const MessageGUID &rhs)
void toHex(char *destination) const
Enum
Enum representing the size of a buffer needed to represent a GUID.
Definition bmqt_messageguid.h:108
@ e_SIZE_BINARY
Binary format of the GUID.
Definition bmqt_messageguid.h:110
@ e_SIZE_HEX
Hexadecimal string representation of the GUID.
Definition bmqt_messageguid.h:114
void toBinary(unsigned char *destination) const
MessageGUID & fromBinary(const unsigned char *buffer)
void hashAppend(HASH_ALGORITHM &hashAlgo, const CorrelationId &value)
Definition bmqt_correlationid.h:504
bsl::ostream & operator<<(bsl::ostream &stream, CompressionAlgorithmType::Enum value)
Definition bmqt_compressionalgorithmtype.h:141
bool operator!=(const CorrelationId &lhs, const CorrelationId &rhs)
Definition bmqt_correlationid.h:582
bool operator==(const CorrelationId &lhs, const CorrelationId &rhs)
Definition bmqt_correlationid.h:576
bool operator<(const CorrelationId &lhs, const CorrelationId &rhs)
Definition bmqt_correlationid.h:588
Definition bmqa_abstractsession.h:42
This struct provides a binary function for comparing 2 GUIDs.
Definition bmqt_messageguid.h:241
bool operator()(const MessageGUID &lhs, const MessageGUID &rhs) const
Definition bmqt_messageguid.h:318