Boost logo

Boost :

Subject: Re: [boost] [Review] UUID library (mini-)review starts today, November 23rd
From: Andy Tompkins (atompkins_at_[hidden])
Date: 2008-12-01 00:02:58


On Sat, 29 Nov 2008 00:14:47 +1100, "Vladimir Batov"
<batov_at_[hidden]> said:
> Andy,
>
> Thank you for taking the criticism the right way and my apologies if
> some of my comments sound(ed) somewhat harsh. It is never my
> intention. I won't be addressing the points below directly as some
> issues I raised are petty (and I somewhat wish I did not raise them).
> I admit I felt uneasy with the proposal but could not pin-point what
> it was. I'll try again.

No offense taken. I value the criticism. It gave my a lot to think
about.

> Background: We are in our project currently using uuid facility
> heavily and very dependent on it. The version we use (from memory) is
> something like (it's not necessarily exactly what we use and I'll omit
> some scaffolding and stick with the basics):
>
> struct uuid : public std::string
> {
> typedef std::string base;
> uuid() : base(generate()) {}
> explicit uuid(string const& s) : base(s) {}
> static uuid null() { return uuid(std::string()); }
> private:
> std::string generate();
> };
>
> On Linux the generate() function calls uuid_generate(). No one (in our
> project anyway) can be bothered choosing between
> uuid_generate_random() or uuid_generate_time() -- uuid_generate()
> takes care of the guess work and picks the best available. The same on
> Windows -- it'll probably be UuidCreate()&UuidToString(). Given that
> uuid above is merely a wrapper over OS facilities, we get known
> behavior, we are guaranteed "support" and an automatic "upgrade"
> if/when the standard changes or a new better algorithm becomes
> available.
>
> For me (a collective nebulous "me") to switch to your boost::uuid it
> has to provide something to win me over. Let's see what that might be.
>
> Does boost::uuid provide superior implementation? Maybe. If it is,
> that was not spelt out sufficiently visibly for me to pick up in the
> documentation. Therefore, as it is now the answer regretfully has to
> be 'no'.

The first thing that comes to mind is size. A uuid class that holds the
data at text (as I believe the above does) will need 32 characters, or
32
bytes. Whereas boost::uuid needs the minimum of 16 bytes. Thus twice
as much space is required. Also many functions (compare, assign, ...)
likely take twice as long with the above implementation.

As a much more minor note, storing a string representation of a uuid
opens
the door to the possibility of the string not actually representing a
valid
uuid. ie "1234567890abcdef!@#$%^&*().{}[]-"

> Does boost::uuid provide superior interface? That issue might get very
> subjective and personal. Therefore, I'll re-focus on if boost::uuid is
> user-friendlier. Maybe but I doubt it as an ordinary user does not
> want to be bothered choosing between algorithms. If uuid_generate()
> and UuidCreate() can make that choice for me, it is good enough for
> the overwhelming majority of uuid applications. Therefore, the answer
> seems again 'no'.

I agree that many users do not care about the algorithm used. If they
really don't care, is it an issue to use the
boost::uuids::uuid_generator
since they don't really care what it does anyway? I believe they would
just use this function and assume all is well. Those who care will look
at what boost::uuids::uuid_generator does and decide for themselves.
They will likely be happy as long as there are the options that they
want.

I do want boost::uuid to provide algorithms to create uuids. I don't
want platforms that don't provide an algorithm to not be able to easily
create a uuid. Thus I don't want boost::uuid to be just a wrapper
around
OS functionality.

> Does boost::uuid provide superior support and a upgrade path? With all
> due respect I have to say 'no' again as your support (no matter how
> enthusiastic it is) cannot compete (on industrial/commercial scale)
> with vendor-backed support. uuid_generate(), UuidCreate() as printf()
> come with the system. One has to have really serious reasons to use
> something else instead.

I would agree, that boost::uuid will never have the support of
industrial/commercial scale. I now think that boost::uuid should
provide
a windows_uuid_generator (that uses UuidCreate), a linux_uuid_generator
(that uses uuid_generate), plus possibility others platform specific
ones,
plus some of it's own. Then a boost::uuids::uuid_generator could use
one of these if available and if not, use it's own generator. This
would
give users the support and upgrade paths that you are talking about.

> Does boost::uuid provide superior documentation? Well, my impression
> is that it is 'no' again.

Again, I plan on improving the documentation.

> What boost::uuid does immediately entice an ordinary user with then it
> is Boost reputation. However, in all honesty it's not boost::uuid
> property per se but the reputation for quality of the Boost libraries
> built over those many years. In this thread I hear some people say
> "it's OK to ship". I disagree. Every new library has Boost reputation
> to uphold. It takes time to build such a reputation. It does not take
> long to lose it -- a couple of just "OK to ship" libraries will
> probably do.

I do hope that Boost's reputation is not all that is going for
boost::uuid.
I value the input of this list (including yours) to help make
boost::uuid
a library that would live up to Boost's reputation.

> I'd probably be more comfortable if boost::uuid took the approach of
> boost::thread of providing consistent interface across many platforms
> via re-use of the functionality provided by the OS (when available)
> rather than duplicating it. Then though I'd expect the interface to be
> given considerably more thought.

As above, I agree that boost::uuid should be able to use functionality
provided by the OS. But it should not require OS functionality to be
useful.

> As for the interface I'll express my view to one of your
> comments below.
>
> > I would not want the default constructor to generate a uuid. I don't
> > want users to pay for that if they don't want it. Some use cases
> > will not require generating uuids, only using them.
>
> I have to disagree. I believe that the overwhelming majority of cases
> falls into the following category -- "I introduce something
> when/because I need that something". That is, by
>
> Foo foo;
> std::string str1;
> std::string str2(params);
> uuid id1;
> uuid id2(param);
>
> I create valid instances. Say, 'str1' is empty but it is still a
> valid string. I create 'id1' because I need an uuid. You on the other
> hand use
>
> uuid id2(param); // valid instance
> uuid id1; // invalid instance
>
> where #1 creates a valid instance but #2 creates an invalid instance
> (it lacks its identifying property -- it's NOT unique). Therefore, you
> use the same (visually and behaviorally) creation mechanism to achieve
> *different* results. From the user perspective it is inconsistent and
> likely unexpected.
>
> The case you are catering for with uuid() is not mainstream but quite
> the opposite -- the user introduces something that he does *not* want.
> Such case should be handled explicitly with the user actually spelling
> out what he means like
>
> Foo::Foo()
> :
> uuid_(boost::uuid::null()) // initially invalid {}

I do believe that a null uuid is a valid uuid, but regardless, if the
common use case really is as you say, then sure lets have the default
constructor call a function to generate a unique uuid. And still
provide a way to create a null uuid.

My work also heavily relies on uuids, but we almost never create one
ourselves in code. We get almost all our uuids from the database
that our program uses. I would be surprised if there aren't many
others that use uuids in the same way, they receive them, they don't
generate them.

> Best, Vladimir.

Regards,
Andy Tompkins


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