From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Jeff Davis <pgsql(at)j-davis(dot)com> |
Cc: | pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: init_htab causes SIGFPE (or worse) due to miscalculation for large nbuckets |
Date: | 2012-12-11 01:27:22 |
Message-ID: | 1036.1355189242@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Jeff Davis <pgsql(at)j-davis(dot)com> writes:
> It looks like all of the callers, except two, immediately shift the
> result. So perhaps it would be better to make a new function (something
> like "ceil_pow2") that returns the lowest power of two greater than or
> equal to the input, and it can return a long (bounded to +LONG_MAX).
That does seem like a good idea. We need one for an int-sized result
too, to fix the original problem in init_htab. So I propose these
functions:
/* calculate ceil(log base 2) of num */
int
my_log2(long num)
{
int i;
long limit;
/* guard against too-large input, which would put us into infinite loop */
if (num > LONG_MAX / 2)
num = LONG_MAX / 2;
for (i = 0, limit = 1; limit < num; i++, limit <<= 1)
;
return i;
}
/* calculate first power of 2 >= num, bounded to what will fit in a long */
long
next_power_of_two_long(long num)
{
/* my_log2's internal range check is sufficient */
return 1L << my_log2(num);
}
/* calculate first power of 2 >= num, bounded to what will fit in an int */
int
next_power_of_two_int(long num)
{
if (num > INT_MAX / 2)
num = INT_MAX / 2;
return 1 << my_log2(num);
}
regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | Jeff Davis | 2012-12-11 02:05:49 | Re: init_htab causes SIGFPE (or worse) due to miscalculation for large nbuckets |
Previous Message | Tom Lane | 2012-12-11 00:52:36 | Re: init_htab causes SIGFPE (or worse) due to miscalculation for large nbuckets |