Rewrite pg_size_pretty() to avoid compiler bug.
authorTom Lane <[email protected]>
Fri, 29 Apr 2011 05:45:13 +0000 (01:45 -0400)
committerTom Lane <[email protected]>
Fri, 29 Apr 2011 05:45:13 +0000 (01:45 -0400)
Convert it to use successive shifts right instead of increasing a divisor.
This is probably a tad more efficient than the original coding, and it's
nicer-looking than the previous patch because we don't need a special case
to avoid overflow in the last branch.  But the real reason to do it is to
avoid a Solaris compiler bug, as per results from buildfarm member moa.

src/backend/utils/adt/dbsize.c

index ab50c06171ea1d78c5fa513ff34b340d55a4a754..76f2f988d49e5b9082c012bdcd5810f28404bab8 100644 (file)
@@ -378,39 +378,33 @@ pg_size_pretty(PG_FUNCTION_ARGS)
    int64       size = PG_GETARG_INT64(0);
    char        buf[64];
    int64       limit = 10 * 1024;
-   int64       mult = 1;
+   int64       limit2 = limit * 2 - 1;
 
-   if (size < limit * mult)
+   if (size < limit)
        snprintf(buf, sizeof(buf), INT64_FORMAT " bytes", size);
    else
    {
-       mult *= 1024;
-       if (size < limit * mult)
+       size >>= 9;             /* keep one extra bit for rounding */
+       if (size < limit2)
            snprintf(buf, sizeof(buf), INT64_FORMAT " kB",
-                    (size + mult / 2) / mult);
+                    (size + 1) / 2);
        else
        {
-           mult *= 1024;
-           if (size < limit * mult)
+           size >>= 10;
+           if (size < limit2)
                snprintf(buf, sizeof(buf), INT64_FORMAT " MB",
-                        (size + mult / 2) / mult);
+                        (size + 1) / 2);
            else
            {
-               mult *= 1024;
-               if (size < limit * mult)
+               size >>= 10;
+               if (size < limit2)
                    snprintf(buf, sizeof(buf), INT64_FORMAT " GB",
-                            (size + mult / 2) / mult);
+                            (size + 1) / 2);
                else
                {
-                   /* Here we have to worry about avoiding overflow */
-                   int64   val;
-
-                   mult *= 1024;
-                   val = size / mult;
-                   if ((size % mult) >= (mult / 2))
-                       val++;
+                   size >>= 10;
                    snprintf(buf, sizeof(buf), INT64_FORMAT " TB",
-                            val);
+                            (size + 1) / 2);
                }
            }
        }