Rewrite pg_size_pretty() to avoid compiler bug.

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.
This commit is contained in:
Tom Lane 2011-04-29 01:44:50 -04:00
parent c49e4ae1f8
commit fd2e2d09aa

View File

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