Re: [SUMMARY] time discussion

2002-07-13 Thread Roy T. Fielding
A fine summary of the situation.
On Friday, July 12, 2002, at 12:42  PM, William A. Rowe, Jr. wrote:
I. We represent all time quantum in the same scale throughout APR.  That
   scale is in microseconds.
Which is goodness, because we don't ever have to go back to docs and ask,
Does that function take seconds or apr time?
It's easy to keep track of that within APR. What is hard is dealing with
both APR and other libraries within the code of APR users, since the rest
of the universe thinks in seconds.  The accessor functions were a
significant improvement.
II. Performance is an issue, we are attempting to reclaim CPU cycles lost
converting, especially between seconds and microseconds, both 
internally
and externally (by other apps.)
And everyone agrees we want this as fast as possible, without introducing
bugs due to [whatever sort of] programmer confusion.
Yes, +1 on applying the binary microseconds patch -- its far better than
the current state.
III. The existing name is an issue to Roy and others who are confused by 
the
 similarity between apr_time_t and time_t (in the ANSI/POSIX 
definitions.)
And I agree it's an obstacle to 1) porting old code to APR, and 2) folks 
quickly
getting comfortable with APR, when they are just learning the library.
I haven't been confused by it.  I just have a better memory of the number
of times that you have patched various aspects of httpd and apr-util
due to people confusing them, or simply changing the interface using
mass find/replace.  Most of those bugs were introduced by the authors
of APR, so I fail to see how just learning applies.
IV. Without sacrificing resolution, I put forward a proposal that we use
a binary representation of microseconds.  Mr. Stoddard has determined
that the binary representation we presented does reduce the overall 
cpu
instructions and clock cycles in httpd request processing, as 
expected.
This has two benefits.  Scalar math operations simply work; computation
of deltas doesn't require additional carry operations.  However, seconds
can be quickly grabbed with a binary shift, so there is no huge integer
division to contend with.  It's an all-around performance win.
However, it's mildly confusing to work with, without the macros.  Those
macros need to be thoroughly vetted for range and overflow errors, etc.
The casts should be removed and the interval time really should
have the same size as epoch time.
V. Aaron and others submit that we should change the name of the type
   if we change the scale, to assure our APR library users aren't 
tripped up
   by casual msec = t / 1000 computations in their existing code.  This 
just
   happens to coincide with Roy's concerns in (III.) above.
And with (III.) above, it just makes good sense to pick new names for this
new type, IF we are going to have a contract with the programmers about
the representation.  We can have compatibility macros until the old 
symbols
are deprecated, and Aaron and others who are concerned with catching all
instances of the old usage can disable the compat macros.
Er, that would have been a good idea, had it been deployed earlier.
VI. Brian and others have asked that we have an undefined scalar value
[with no contract to the users about it's representation.]  Roy and 
others
object, due to overflow and range considerations, and binary 
compatibility
considerations [as it's all in macros that aren't updated by new 
binaries].
I really don't see a win here.  Why have no contract?  We aren't hiding 
the
definitions within accessor functions behind an opaque type.  There is NO
type safety when you use C scalars for a type.

And the code can never be binary drop-in replaceable, the time 
manipulation
was all compiled into the user's code from the macros, it isn't buried 
safely
inside of APR.
I just don't believe in partially-implemented ADTs.  It needs to be
either abstract to hide implementation details or written in stone
such that the implementation details are guaranteed across platforms.
One or the other is okay with me, but not both.
VII. Ryan and others submit that we need two types, in fact; one absolute
 measure (from epoch 1.1.1970) and one 'interval' or 'delta' that 
represents
 a span, rather than a time.  This is the case in APR today.
And we all agree here.  The key words, time and span make the most sense
after I considered it.  span is fairly well adopted in the C/C++/STL 
world.

VIII. From all of the above came the original discussion of naming.  
Ryan and
  others believe we should not change the name of the type, 
whatsoever.
  The sub-argument is between a strongly defined name contract, e.g.
  busec in the identifier, or a completely ambigious name with no 
contract
  of the scale's unit.
And I stand on a strongly named, intuitive names that warn you not to just
pass around seconds.  That leaves us with something like;
apr_time_busec_t
apr_span_busec_t
which conveys that the span is measured in 

[SUMMARY] time discussion

2002-07-12 Thread William A. Rowe, Jr.
At 01:47 PM 7/12/2002, David Reid wrote
Can someone simply restate what issue needs fixing. No more hand waving or
IRC chats, a simple email explaining the issue and what needs fixed.
I will try to do so in a fair and balanced way;
I. We represent all time quantum in the same scale throughout APR.  That
   scale is in microseconds.
II. Performance is an issue, we are attempting to reclaim CPU cycles lost
converting, especially between seconds and microseconds, both internally
and externally (by other apps.)
III. The existing name is an issue to Roy and others who are confused by the
 similarity between apr_time_t and time_t (in the ANSI/POSIX definitions.)
IV. Without sacrificing resolution, I put forward a proposal that we use
a binary representation of microseconds.  Mr. Stoddard has determined
that the binary representation we presented does reduce the overall cpu
instructions and clock cycles in httpd request processing, as expected.
V. Aaron and others submit that we should change the name of the type
   if we change the scale, to assure our APR library users aren't tripped up
   by casual msec = t / 1000 computations in their existing code.  This just
   happens to coincide with Roy's concerns in (III.) above.
VI. Brian and others have asked that we have an undefined scalar value
[with no contract to the users about it's representation.]  Roy and others
object, due to overflow and range considerations, and binary compatibility
considerations [as it's all in macros that aren't updated by new 
binaries].

VII. Ryan and others submit that we need two types, in fact; one absolute
 measure (from epoch 1.1.1970) and one 'interval' or 'delta' that 
represents
 a span, rather than a time.  This is the case in APR today.

VIII. From all of the above came the original discussion of naming.  Ryan and
  others believe we should not change the name of the type, whatsoever.
  The sub-argument is between a strongly defined name contract, e.g.
  busec in the identifier, or a completely ambigious name with no contract
  of the scale's unit.
IX. Roy's original comments yesterday went back to item (II.) above, and
reintroduced to the optimization discussion the options of either using
seconds to those apr functions that don't need precision, and/or 
replacing
our time definition with a structure (seperate seconds and useconds 
fields.)
These options were debated/voted upon several times before on the APR 
list.

I hope this is a balanced and fair summary of the discussion to date.
My unbalanced opinions are a topic for another post.
Bill



Re: [SUMMARY] time discussion

2002-07-12 Thread Jim Jagielski
William A. Rowe, Jr. wrote:
 
 I hope this is a balanced and fair summary of the discussion to date.
 

Lovely. 

-- 
===
   Jim Jagielski   [|]   [EMAIL PROTECTED]   [|]   http://www.jaguNET.com/
  A society that will trade a little liberty for a little order
 will lose both and deserve neither - T.Jefferson


Re: [SUMMARY] time discussion

2002-07-12 Thread William A. Rowe, Jr.
Now my own comments;

I. We represent all time quantum in the same scale throughout APR.  That
   scale is in microseconds.
Which is goodness, because we don't ever have to go back to docs and ask,
Does that function take seconds or apr time?
II. Performance is an issue, we are attempting to reclaim CPU cycles lost
converting, especially between seconds and microseconds, both internally
and externally (by other apps.)
And everyone agrees we want this as fast as possible, without introducing
bugs due to [whatever sort of] programmer confusion.
III. The existing name is an issue to Roy and others who are confused by the
 similarity between apr_time_t and time_t (in the ANSI/POSIX 
definitions.)
And I agree it's an obstacle to 1) porting old code to APR, and 2) folks 
quickly
getting comfortable with APR, when they are just learning the library.

IV. Without sacrificing resolution, I put forward a proposal that we use
a binary representation of microseconds.  Mr. Stoddard has determined
that the binary representation we presented does reduce the overall cpu
instructions and clock cycles in httpd request processing, as expected.
This has two benefits.  Scalar math operations simply work; computation
of deltas doesn't require additional carry operations.  However, seconds
can be quickly grabbed with a binary shift, so there is no huge integer
division to contend with.  It's an all-around performance win.
However, it's mildly confusing to work with, without the macros.  Those
macros need to be thoroughly vetted for range and overflow errors, etc.
V. Aaron and others submit that we should change the name of the type
   if we change the scale, to assure our APR library users aren't tripped up
   by casual msec = t / 1000 computations in their existing code.  This just
   happens to coincide with Roy's concerns in (III.) above.
And with (III.) above, it just makes good sense to pick new names for this
new type, IF we are going to have a contract with the programmers about
the representation.  We can have compatibility macros until the old symbols
are deprecated, and Aaron and others who are concerned with catching all
instances of the old usage can disable the compat macros.
VI. Brian and others have asked that we have an undefined scalar value
[with no contract to the users about it's representation.]  Roy and 
others
object, due to overflow and range considerations, and binary 
compatibility
considerations [as it's all in macros that aren't updated by new 
binaries].
I really don't see a win here.  Why have no contract?  We aren't hiding the
definitions within accessor functions behind an opaque type.  There is NO
type safety when you use C scalars for a type.
And the code can never be binary drop-in replaceable, the time manipulation
was all compiled into the user's code from the macros, it isn't buried safely
inside of APR.
VII. Ryan and others submit that we need two types, in fact; one absolute
 measure (from epoch 1.1.1970) and one 'interval' or 'delta' that 
represents
 a span, rather than a time.  This is the case in APR today.
And we all agree here.  The key words, time and span make the most sense
after I considered it.  span is fairly well adopted in the C/C++/STL world.
VIII. From all of the above came the original discussion of naming.  Ryan and
  others believe we should not change the name of the type, whatsoever.
  The sub-argument is between a strongly defined name contract, e.g.
  busec in the identifier, or a completely ambigious name with no 
contract
  of the scale's unit.
And I stand on a strongly named, intuitive names that warn you not to just
pass around seconds.  That leaves us with something like;
apr_time_busec_t
apr_span_busec_t
which conveys that the span is measured in buseconds.
I'm suggesting the time/span before busec so we don't have to go about
renaming EVERY SINGLE apr_time_fn() to a new type.  Can we all live
with apr_time_() functions addressing apr_time_busec_t values?  Or do
we have to go to the extreme of renaming these all apr_time_busec_fn()?
IX. Roy's original comments yesterday went back to item (II.) above, and
reintroduced to the optimization discussion the options of either using
seconds to those apr functions that don't need precision, and/or 
replacing
our time definition with a structure (seperate seconds and useconds 
fields.)
These options were debated/voted upon several times before on the APR 
list.
To the idea of both a seconds and a fine-resolution time type in APR... I 
say
no friggin way.  All of us have introduced bugs in code at one time or another
by mixing up our seconds, mseconds and useconds, no?
One scale for time in APR is sufficient.  That's the way NSPR went as well, 
IIRC.

To the other idea of going back to a structure, that has a huge performance
penalty when you need to compute deltas.  Simple add/subtract becomes
10+ cpu instructions.  That's the main objection 

Re: [SUMMARY] time discussion

2002-07-12 Thread Justin Erenkrantz
On Fri, Jul 12, 2002 at 02:42:22PM -0500, William A. Rowe, Jr. wrote:
 And with (III.) above, it just makes good sense to pick new names for this
 new type, IF we are going to have a contract with the programmers about
 the representation.  We can have compatibility macros until the old symbols
 are deprecated, and Aaron and others who are concerned with catching all
 instances of the old usage can disable the compat macros.

Nope, compatibility macros can't work since the claim is that people
are directly altering the values.  If they used the functions, then
the complaint about backwards-compatibility would be moot.

 VI. Brian and others have asked that we have an undefined scalar value
  [with no contract to the users about it's representation.]  Roy and 
  others
  object, due to overflow and range considerations, and binary 
  compatibility
  considerations [as it's all in macros that aren't updated by new 
  binaries].
 
 I really don't see a win here.  Why have no contract?  We aren't hiding the
 definitions within accessor functions behind an opaque type.  There is NO
 type safety when you use C scalars for a type.
 
 And the code can never be binary drop-in replaceable, the time manipulation
 was all compiled into the user's code from the macros, it isn't buried safely
 inside of APR.

I maintain that it should be undefined so that on source-compatible
releases, we can switch the types.  On binary-compatible release, we
can't touch it though.  (Greg and Ryan have defined this well.)

I'm slowly beginning to believe that apr_time_t *should* be entirely
opaque.  

#define apr_time_diff(time1,time2) time1-time2
...

But, in APR 2.0 (or the next source-compatible release), if we wanted
to we could make it a function such that (not that we would do
this example for reasons you point out later):

apr_span_t apr_time_diff(apr_time_t t1, apr_time_t t2)
{
apr_span_t t3;
t3.sec = t1.sec - t2.usec;
t3.usec = t1.usec - t2.usec;
return t3;
}

The fact that we exposed the time structure at all is the reason that
we are in this predicament.  Merely changing the type name would not
be a win, either.  If we make it unspecified, we have to make sure
that direct modification of apr_time_t is not allowed.

 VIII. From all of the above came the original discussion of naming.  Ryan and
others believe we should not change the name of the type, whatsoever.
The sub-argument is between a strongly defined name contract, e.g.
busec in the identifier, or a completely ambigious name with no 
  contract
of the scale's unit.
 
 And I stand on a strongly named, intuitive names that warn you not to just
 pass around seconds.  That leaves us with something like;
 
 apr_time_busec_t
 apr_span_busec_t
 
 which conveys that the span is measured in buseconds.
 
 I'm suggesting the time/span before busec so we don't have to go about
 renaming EVERY SINGLE apr_time_fn() to a new type.  Can we all live
 with apr_time_() functions addressing apr_time_busec_t values?  Or do
 we have to go to the extreme of renaming these all apr_time_busec_fn()?

No, if you buy in the apr_time_busec_t argument, all of the functions
have to be renamed.  The reason is that I can come along with a
apr_time_dsec_t implementation.  If we have an explicit contract,
we MUST make the API specific to that contract.  No apr_time_now(),
etc.  It has to be apr_time_busec_now(), etc.  

Personally, I think the proponents of the busec contract are going
to paint ourselves in a tight corner if we do find something wrong
with that implementation down the road.  I would much prefer that
we allow ourselves to change implementations without changing the
API.  I believe that the explicit contract solution for busec will
come back to haunt us.  -- justin