libbmq  a5f8a06ba1d16cb5a65643e1fa7f1a1d6aadef40
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 <bslh_hash.h>
80 #include <bslmf_isbitwiseequalitycomparable.h>
81 #include <bslmf_istriviallycopyable.h>
82 #include <bslmf_nestedtraitdeclaration.h>
83 #include <bsls_annotation.h>
84 #include <bsls_types.h>
85 
86 namespace BloombergLP {
87 namespace bmqt {
88 
89 // =================
90 // class MessageGUID
91 // =================
92 
95 class MessageGUID {
96  // FRIENDS
97  friend bool operator==(const MessageGUID& lhs, const MessageGUID& rhs);
98  friend bool operator!=(const MessageGUID& lhs, const MessageGUID& rhs);
99  friend struct MessageGUIDLess;
100  template <class HASH_ALGORITHM>
101  friend void hashAppend(HASH_ALGORITHM& hashAlgo, const MessageGUID& guid);
102 
103  public:
104  // TYPES
105 
107  enum Enum {
109  e_SIZE_BINARY = 16
110 
111  ,
114  };
115 
116  // TRAITS
117  BSLMF_NESTED_TRAIT_DECLARATION(MessageGUID,
118  bslmf::IsBitwiseEqualityComparable)
119  BSLMF_NESTED_TRAIT_DECLARATION(MessageGUID, bsl::is_trivially_copyable)
120 
121  private:
122  // PRIVATE CONSTANTS
123 
125  static const char k_UNSET_GUID[e_SIZE_BINARY];
126 
127  private:
128  // IMPLEMENTATION NOTE: Some structs in bmqp::Protocol.h blindly
129  // reinterpret_cast a char[e_SIZE_BINARY] to a
130  // MessageGUID (instead of using 'fromBinary()') so
131  // that they can return a const MessageGUID&.
132  // IMPLEMENTATION NOTE: See mqbu_messageguidutil.cpp for internal layout of
133  // MessageGUID
134 
135  // DATA
136  char d_buffer[e_SIZE_BINARY];
137 
138  public:
139  // CLASS METHODS
140 
144  static bool isValidHexRepresentation(const char* buffer);
145 
146  // CREATORS
147 
150  MessageGUID();
151 
153  ~MessageGUID();
154 
155  // MANIPULATORS
156 
161  MessageGUID& fromBinary(const unsigned char* buffer);
162 
168  MessageGUID& fromHex(const char* buffer);
169 
170  // ACCESSORS
171 
173  bool isUnset() const;
174 
179  void toBinary(unsigned char* destination) const;
180 
185  void toHex(char* destination) const;
186 
199  bsl::ostream&
200  print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const;
201 };
202 
203 // FREE OPERATORS
204 
205 // -----------------
206 // class MessageGUID
207 // -----------------
208 
214 bsl::ostream& operator<<(bsl::ostream& stream, const MessageGUID& rhs);
215 
219 bool operator==(const MessageGUID& lhs, const MessageGUID& rhs);
220 
224 bool operator!=(const MessageGUID& lhs, const MessageGUID& rhs);
225 
233 bool operator<(const MessageGUID& lhs, const MessageGUID& rhs);
234 
235 // =====================
236 // class MessageGUIDLess
237 // =====================
238 
241  // ACCESSORS
242 
245  bool operator()(const MessageGUID& lhs, const MessageGUID& rhs) const;
246 };
247 
248 // =========================
249 // class MessageGUIDHashAlgo
250 // =========================
251 
258  private:
259  // DATA
260  bsls::Types::Uint64 d_result;
261 
262  public:
263  // TYPES
264  typedef bsls::Types::Uint64 result_type;
265 
266  // CREATORS
267 
270 
271  // MANIPULATORS
272  void operator()(const void* data, size_t numBytes);
273 
276 };
277 
278 // ============================================================================
279 // INLINE DEFINITIONS
280 // ============================================================================
281 
282 // -----------------
283 // class MessageGUID
284 // -----------------
285 
286 // CREATORS
288 {
289  bsl::memcpy(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
290 }
291 
293 {
294 #ifdef BSLS_ASSERT_SAFE_IS_ACTIVE
295  bsl::memcpy(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
296 #endif
297 }
298 
299 // ACCESSORS
300 inline bool MessageGUID::isUnset() const
301 {
302  return 0 == bsl::memcmp(d_buffer, k_UNSET_GUID, e_SIZE_BINARY);
303 }
304 
305 // FREE FUNCTIONS
306 template <class HASH_ALGORITHM>
307 void hashAppend(HASH_ALGORITHM& hashAlgo, const MessageGUID& guid)
308 {
309  using bslh::hashAppend; // for ADL
310  hashAppend(hashAlgo, guid.d_buffer); // hashes entire buffer array
311 }
312 
313 // ----------------------
314 // struct MessageGUIDLess
315 // ----------------------
316 
318  const MessageGUID& rhs) const
319 {
320  return 0 >
321  bsl::memcmp(lhs.d_buffer, rhs.d_buffer, MessageGUID::e_SIZE_BINARY);
322 }
323 
324 // -------------------------
325 // class MessageGUIDHashAlgo
326 // -------------------------
327 
328 // CREATORS
330 : d_result(0)
331 {
332 }
333 
334 // MANIPULATORS
335 inline void
337  BSLS_ANNOTATION_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 
380 {
381  return d_result;
382 }
383 
384 } // close package namespace
385 
386 // -----------------
387 // class MessageGUID
388 // -----------------
389 
390 // FREE OPERATORS
391 inline 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 
398 inline bool bmqt::operator!=(const bmqt::MessageGUID& lhs,
399  const bmqt::MessageGUID& rhs)
400 {
401  return !(lhs == rhs);
402 }
403 
404 inline bool bmqt::operator<(const bmqt::MessageGUID& lhs,
405  const bmqt::MessageGUID& rhs)
406 {
407  MessageGUIDLess less;
408  return less(lhs, rhs);
409 }
410 
411 inline 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:257
MessageGUIDHashAlgo()
Constructor.
Definition: bmqt_messageguid.h:329
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:264
Definition: bmqt_messageguid.h:95
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
friend bool operator!=(const MessageGUID &lhs, const MessageGUID &rhs)
MessageGUID()
Definition: bmqt_messageguid.h:287
bool isUnset() const
Return true if the value of this object is not set.
Definition: bmqt_messageguid.h:300
MessageGUID & fromBinary(const unsigned char *buffer)
~MessageGUID()
Destructor.
Definition: bmqt_messageguid.h:292
friend void hashAppend(HASH_ALGORITHM &hashAlgo, const MessageGUID &guid)
Definition: bmqt_messageguid.h:307
static bool isValidHexRepresentation(const char *buffer)
friend bool operator==(const MessageGUID &lhs, const MessageGUID &rhs)
void toHex(char *destination) const
MessageGUID & fromHex(const char *buffer)
Enum
Enum representing the size of a buffer needed to represent a GUID.
Definition: bmqt_messageguid.h:107
@ e_SIZE_BINARY
Binary format of the GUID.
Definition: bmqt_messageguid.h:109
@ e_SIZE_HEX
Hexadecimal string representation of the GUID.
Definition: bmqt_messageguid.h:113
void toBinary(unsigned char *destination) const
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
void hashAppend(HASH_ALGORITHM &hashAlgo, const MessageGUID &guid)
Definition: bmqt_messageguid.h:307
Definition: bmqa_abstractsession.h:42
This struct provides a binary function for comparing 2 GUIDs.
Definition: bmqt_messageguid.h:240
bool operator()(const MessageGUID &lhs, const MessageGUID &rhs) const
Definition: bmqt_messageguid.h:317