Boost logo

Boost :

From: Andy (atompkins_at_[hidden])
Date: 2007-05-07 10:56:03


Matthias Troyer <troyer_at_[hidden]> wrote in
news:F45D2822-2671-4B1B-B930-3A56E9CEF1C5_at_[hidden]:

>
> On 6 May 2007, at 14:37, Peter Dimov wrote:
>
>> Matthias Troyer wrote:
>>> On 5 May 2007, at 06:16, Peter Dimov wrote:
>>>> * I agree that the time(0) seed is unacceptable. A good source of
>>>> entropy
>>>> probably deserves its own library. It's also not easy to make it
>>>> header-only. One compromise could be for the create function to
>>>> take an
>>>> Engine argument, but this takes away the simplicity.
>>>
>>> How about just adding an additional create function that takes an
>>> engine?
>>
>> The existing create function is dangerous as it doesn't generate
>> reasonably
>> unique identifiers. We can't fix that by adding more overloads.
>
> I fully agree that it is very dangerous, especially on parallel
> machines. However, in addition to fixing this, it would be good to
> have the engine be customizable.
>
> Matthias

I agree that the create function needs improvement. It suffers from
threading problems (because of static variables) and from a hard coded
random number generator (also a hard coded seed).

My solution is to create a generator class, as follows:

// maybe a better name
// maybe a different default random number generator
template <typename UniformRandomNumberGenerator = boost::mt19937>
class random_guid_generator : boost::noncopyable
{
  typedef boost::uniform_int<uint8_t> DistributionType;
public:
  explicit random_guid_generator(UniformRandomNumberGenerator& engine
    = boost::mt19937(time(0)))
    : engine_(engine)
    , generator_(engine_, DistributionType(0, 255))
  {}

  guid create()
  {
    guid g;
    // create guid using generator_()
    return g;
  }

private:
  UniformRandomNumberGenerator& engine_;
  boost::variate_generator<UniformRandomNumberGenerator&,
    DistributionType> generator_;
};

to be used like:

random_guid_generator<> guid_gen;
guid g = guid_gen.create();

or:

uint32_t seed = 0; // get good seed
boost::lagged_fibonacci44497 engine(seed);
random_guid_generator<boost::lagged_fibonacci44497> guid_gen(engine);
guid g = guid_gen.create();

or:

boost::random_device engine;
random_guid_generator<boost::random_device> guid_gen(engine);
guid g = guid_gen.create();

One could have a random_guid_generator per thread/processor/... solving
the threading problems. Also one can provide any random number
generator that satisfies the Uniform Random Number Generator concept
from the Boost.Random library.

Andy.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk