Gmane
From: Andy <atompkins <at> fastmail.fm>
Subject: Re: [review] Boost.Guid
Newsgroups: gmane.comp.lib.boost.devel
Date: 2007-05-07 14:56:03 GMT (1 year, 17 weeks, 5 days, 21 hours and 53 minutes ago)
Matthias Troyer <troyer <at> phys.ethz.ch> wrote in
news:F45D2822-2671-4B1B-B930-3A56E9CEF1C5 <at> phys.ethz.ch: 

> 
> 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.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost