pion-net  4.0.9
PionId.hpp
1 // -----------------------------------------------------------------------
2 // pion-common: a collection of common libraries used by the Pion Platform
3 // -----------------------------------------------------------------------
4 // Copyright (C) 2007-2009 Atomic Labs, Inc. (http://www.atomiclabs.com)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_PIONID_HEADER__
11 #define __PION_PIONID_HEADER__
12 
13 #include <string>
14 #include <limits>
15 #include <ctime>
16 #include <cstring>
17 #include <cstdlib>
18 #include <boost/functional/hash.hpp>
19 #include <boost/date_time/posix_time/posix_time.hpp>
20 #include <boost/random/uniform_int.hpp>
21 #include <boost/random/variate_generator.hpp>
22 #include <boost/random/mersenne_twister.hpp>
23 #include <boost/numeric/conversion/cast.hpp>
24 #include <pion/PionConfig.hpp>
25 
26 namespace pion { // begin namespace pion
27 
28 
32 class PionId {
33 public:
34 
36  typedef unsigned char * iterator;
37 
39  typedef const unsigned char * const_iterator;
40 
41  enum {
42  PION_ID_DATA_BYTES = 16, //< total number of data bytes
43  PION_ID_HEX_BYTES = 16 * 2 + 4 //< number of bytes in hexadecimal representation
44  };
45 
47  virtual ~PionId() {}
48 
50  PionId(void) {
51  typedef boost::mt19937 gen_type;
52  typedef boost::uniform_int<unsigned long> dist_type;
53  typedef boost::variate_generator<gen_type,dist_type> die_type;
54  gen_type rng_gen(PionId::make_seed());
55  dist_type rng_dist((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::max)());
56  die_type rng_die(rng_gen, rng_dist);
57  generate(m_data, rng_die);
58  }
59 
61  explicit PionId(const std::string& str) {
62  from_string(str.c_str());
63  }
64 
66  explicit PionId(const char *str) {
67  from_string(str);
68  }
69 
71  template<typename base_generator_type, typename distribution_type>
72  explicit PionId(boost::variate_generator<base_generator_type, distribution_type>& rng) {
73  generate(m_data, rng);
74  }
75 
77  PionId(const PionId& id) {
78  memcpy(m_data, id.m_data, PION_ID_DATA_BYTES);
79  }
80 
82  PionId& operator=(const PionId& id) {
83  memcpy(m_data, id.m_data, PION_ID_DATA_BYTES);
84  return *this;
85  }
86 
88  inline unsigned char operator[](const std::size_t n) const {
89  return m_data[n];
90  }
91 
93  inline bool operator==(const PionId& id) const {
94  return (memcmp(m_data, id.m_data, PION_ID_DATA_BYTES) == 0);
95  }
96 
98  inline bool operator!=(const PionId& id) const {
99  return (memcmp(m_data, id.m_data, PION_ID_DATA_BYTES) != 0);
100  }
101 
103  inline bool operator<(const PionId& id) const {
104  return (memcmp(m_data, id.m_data, PION_ID_DATA_BYTES) < 0);
105  }
106 
108  inline bool operator>(const PionId& id) const {
109  return (memcmp(m_data, id.m_data, PION_ID_DATA_BYTES) > 0);
110  }
111 
113  inline iterator begin(void) { return m_data; }
114 
116  inline iterator end(void) { return m_data + PION_ID_DATA_BYTES; }
117 
119  inline const_iterator begin(void) const { return m_data; }
120 
122  inline const_iterator end(void) const { return m_data + PION_ID_DATA_BYTES; }
123 
125  inline std::string to_string(void) const {
126  std::string hex_str;
127  static const char hex[] = "0123456789abcdef";
128  for (std::size_t i = 0; i < PION_ID_DATA_BYTES; i++) {
129  hex_str += hex[m_data[i] >> 4];
130  hex_str += hex[m_data[i] & 0x0f];
131  if (i == 3 || i == 5 || i == 7 || i == 9)
132  hex_str += '-';
133  }
134  return hex_str;
135  }
136 
138  void from_string(const char *str) {
139  std::size_t data_pos = 0;
140  char buf[3];
141  buf[2] = '\0';
142  while (*str != '\0' && data_pos < PION_ID_DATA_BYTES) {
143  if (isxdigit(*str)) {
144  buf[0] = *str;
145  if (*(++str) == '\0' || !isxdigit(*str)) // sanity check
146  break;
147  buf[1] = *str;
148  m_data[data_pos++] = boost::numeric_cast<unsigned char>(strtoul(buf, NULL, 16));
149  }
150  ++str;
151  }
152  }
153 
155  static inline boost::uint32_t make_seed(void) {
156  // this could probably be much better, but trying to KISS...
157  typedef boost::mt19937 gen_type;
158  typedef boost::uniform_int<unsigned long> dist_type;
159  typedef boost::variate_generator<gen_type,dist_type> die_type;
160  // initialize a static generator with seed based upon system time
161  static boost::uint64_t seed_seed_64 = (time(NULL) * 1000000) + boost::posix_time::microsec_clock::local_time().time_of_day().total_microseconds();
162  // Convert to 32 bits, keeping most of the available entropy.
163  static gen_type::result_type seed_seed_32 = boost::numeric_cast<gen_type::result_type>((seed_seed_64 >> 32) ^ (seed_seed_64 & 0xFFFFFFFF));
164  static gen_type rng_gen(seed_seed_32);
165  static dist_type rng_dist((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::max)());
166  static die_type rng_die(rng_gen, rng_dist);
167  // use the static rng to produce seed values that initialize other generators
168  return rng_die();
169  }
170 
171 
172 protected:
173 
180  template<typename base_generator_type, typename distribution_type>
181  static inline void generate(unsigned char *data, boost::variate_generator<base_generator_type, distribution_type>& rng) {
182  // Note: this code is adapted from the Boost UUID library, (c) 2006 Andy Tompkins
183  for (std::size_t i = 0; i < PION_ID_DATA_BYTES; i += sizeof(unsigned long)) {
184  *reinterpret_cast<unsigned long*>(&data[i]) = rng();
185  }
186 
187  // set variant
188  // should be 0b10xxxxxx
189  data[8] &= 0xBF;
190  data[8] |= 0x80;
191 
192  // set version
193  // should be 0b0100xxxx
194  data[6] &= 0x4F; //0b01001111
195  data[6] |= 0x40; //0b01000000
196  }
197 
199  unsigned char m_data[PION_ID_DATA_BYTES];
200 };
201 
202 
204 static inline std::size_t hash_value(const PionId& id) {
205  std::size_t seed = 0;
206  const unsigned char * data = id.begin();
207  const unsigned char * const end = id.end();
208  while (data < end) {
209  boost::hash_combine(seed, *reinterpret_cast<const unsigned long*>(data));
210  data += sizeof(unsigned long);
211  }
212  return seed;
213 }
214 
215 
219 template <typename BaseGeneratorType>
221 public:
222 
224  typedef BaseGeneratorType base_generator_type;
225 
227  typedef boost::uniform_int<unsigned long> distribution_type;
228 
230  typedef boost::variate_generator<base_generator_type, distribution_type> gen_type;
231 
232 
234  virtual ~PionIdGeneratorBase() {}
235 
238  : m_random_gen(PionId::make_seed()),
239  m_random_dist((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::max)()),
241  {}
242 
244  inline PionId operator()(void) { return PionId(m_random_die); }
245 
247  inline gen_type& getRNG(void) { return m_random_die; }
248 
250  inline unsigned long getNumber(void) { return m_random_die(); }
251 
252 
253 protected:
254 
257 
260 
263 };
264 
265 
268 
269 
270 } // end namespace pion
271 
272 #endif
PionId(const PionId &id)
copy constructor
Definition: PionId.hpp:77
BaseGeneratorType base_generator_type
make dynamic type for base generator available
Definition: PionId.hpp:224
PionId & operator=(const PionId &id)
assignment operator
Definition: PionId.hpp:82
PionId(boost::variate_generator< base_generator_type, distribution_type > &rng)
construction using an existing random number generator
Definition: PionId.hpp:72
PionId(const std::string &str)
construction using a string representation (bb49b9ca-e733-47c0-9a26-0f8f53ea1660) ...
Definition: PionId.hpp:61
const_iterator end(void) const
returns the ending iterator (const)
Definition: PionId.hpp:122
bool operator<(const PionId &id) const
returns true if id is less than this
Definition: PionId.hpp:103
const unsigned char * const_iterator
const data type for iterating PionId byte values
Definition: PionId.hpp:39
boost::uniform_int< unsigned long > distribution_type
random number distribution type
Definition: PionId.hpp:227
iterator begin(void)
returns the beginning iterator
Definition: PionId.hpp:113
gen_type m_random_die
random number die
Definition: PionId.hpp:262
void from_string(const char *str)
sets the data value based upon a null-terminated string representation (bb49b9ca-e733-47c0-9a26-0f8f5...
Definition: PionId.hpp:138
PionId(const char *str)
construction using a null-terminated c-style string (bb49b9ca-e733-47c0-9a26-0f8f53ea1660) ...
Definition: PionId.hpp:66
unsigned long getNumber(void)
return random number generator
Definition: PionId.hpp:250
unsigned char operator[](const std::size_t n) const
returns id value at byte offset
Definition: PionId.hpp:88
unsigned char * iterator
data type for iterating PionId byte values
Definition: PionId.hpp:36
static void generate(unsigned char *data, boost::variate_generator< base_generator_type, distribution_type > &rng)
Definition: PionId.hpp:181
const_iterator begin(void) const
returns the beginning iterator (const)
Definition: PionId.hpp:119
PionId operator()(void)
returns a newly generated PionId object
Definition: PionId.hpp:244
PionId(void)
default constructor
Definition: PionId.hpp:50
bool operator!=(const PionId &id) const
returns true if id does not equal this
Definition: PionId.hpp:98
base_generator_type m_random_gen
random number generator
Definition: PionId.hpp:256
static boost::uint32_t make_seed(void)
return a seed value for random number generators
Definition: PionId.hpp:155
boost::variate_generator< base_generator_type, distribution_type > gen_type
random number generator type
Definition: PionId.hpp:230
virtual ~PionIdGeneratorBase()
class may be extended (virtual destructor)
Definition: PionId.hpp:234
unsigned char m_data[PION_ID_DATA_BYTES]
sequence of bytes representing the unique identifier
Definition: PionId.hpp:199
bool operator==(const PionId &id) const
returns true if id equals this
Definition: PionId.hpp:93
PionIdGeneratorBase< boost::mt19937 > PionIdGenerator
data type for the default PionId generator class
Definition: PionId.hpp:267
distribution_type m_random_dist
random number distribution
Definition: PionId.hpp:259
PionIdGeneratorBase(void)
default constructor
Definition: PionId.hpp:237
gen_type & getRNG(void)
return random number generator
Definition: PionId.hpp:247
iterator end(void)
returns the ending iterator
Definition: PionId.hpp:116
virtual ~PionId()
class may be extended (virtual destructor)
Definition: PionId.hpp:47
bool operator>(const PionId &id) const
returns true if id is greater than this
Definition: PionId.hpp:108
std::string to_string(void) const
returns hexadecimal representation as a string (bb49b9ca-e733-47c0-9a26-0f8f53ea1660) ...
Definition: PionId.hpp:125