[concurrency-interest] Durations in existing JDK APIs

Martin Buchholz martinrb at google.com
Mon Jun 4 23:52:26 EDT 2018


Looks like if you switch representation for negative Duration, much of the
hair goes away.
This version also optimizes for NANOSECONDS, which is very likely to be the
target in practice:

    public long convert(Duration duration) {
        long secs = duration.getSeconds();
        int nano = duration.getNano();
        if (secs < 0 && nano > 0) {
            // use representation compatible with integer division
            secs++;
            nano -= SECOND_SCALE;
        }
        final long s;
        if ((s = scale) >= SECOND_SCALE)
            return (s == SECOND_SCALE) ? secs : secs / secRatio;
        long val = secs * secRatio + ((s == NANO_SCALE) ? nano : nano / s);
        return ((secs | nano) >= 0)
            ? ((secs > maxSecs || val < 0) ? Long.MAX_VALUE : val)
            : ((secs < -maxSecs || val > 0) ? Long.MIN_VALUE : val);
    }


On Mon, Jun 4, 2018 at 2:47 PM, Martin Buchholz <martinrb at google.com> wrote:

> TimeUnit#toDuration is gone.
>
> Here's a non-strawman attempt at TimeUnit#convert(Duration).
> I was astonished how hard it was to get this really correct instead of
> merely mostly correct.
> For negative numbers, the long/int representation of Duration is sort-of a
> "floored" division instead of java's default "truncating" division.
>
>     public long convert(Duration duration) {
>         final long secs = duration.getSeconds();
>         final int nano = duration.getNano();
>         final long s, candidate;
>         if ((s = scale) == SECOND_SCALE)
>             return (secs < 0 && nano > 0) ? secs + 1 : secs;
>         if (s > SECOND_SCALE) {
>             long div = secs / secRatio;
>             if (secs < 0 && nano > 0 && div * secRatio == secs)
>                 div++;
>             return div;
>         }
>         return (secs >= 0)
>             ? ((secs > maxSecs
>                 || (candidate = secs * secRatio + nano / s) < 0)
>                ? Long.MAX_VALUE : candidate)
>             : ((secs < - maxSecs - 1
>                 || (candidate = secs * secRatio + (nano + s - 1) / s) > 0)
>                ? Long.MIN_VALUE : candidate);
>     }
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20180604/2acf433e/attachment-0001.html>


More information about the Concurrency-interest mailing list