mirror of
https://github.com/postgres/postgres.git
synced 2026-10-25 01:39:28 +03:00
Fix incorrect nmembers calculation in test_bitmapset
This calculation was failing to correctly account for the min_value when calculating how many random members to add to the Bitmapset. What the code was meant to do was add a random number of members between the minimum and maximum values. The code failed to account for the minimum value being non-zero, which could result in too many members being added to the set, which could reduce the effectiveness of the test. In reality, the only caller to this function did pass 0 as the min_value, so there is no live bug being fixed here. Fix this so that the Bitmapset is more sparsely populated with members between the minimum and maximum values. In passing, swap the order of the min_value and max_value parameters. Having the minimum value appear before the maximum value makes more sense. Also align the names of both parameters, and adjust the 'offset' calculation to widen the offset range by 1 so that the possible range for that random value is -max_value to max_value. Author: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Greg Burd <greg@burd.me> Discussion: https://postgr.es/m/CAApHDvpfZqdMRmR-6W9UXb+Tanex5wK6PsL=XzYCV4P3pD36Ng@mail.gmail.com
This commit is contained in:
@@ -1650,7 +1650,7 @@ SELECT test_random_operations(NULL, 10000, 81920, 0) > 0 AS result;
|
||||
(1 row)
|
||||
|
||||
-- perform some random tests on bms_offset_members()
|
||||
SELECT test_random_offset_operations(NULL, 1000, 1024, 0) AS result;
|
||||
SELECT test_random_offset_operations(NULL, 1000, 0, 1024) AS result;
|
||||
result
|
||||
--------
|
||||
1000
|
||||
|
||||
@@ -424,6 +424,6 @@ SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result;
|
||||
SELECT test_random_operations(NULL, 10000, 81920, 0) > 0 AS result;
|
||||
|
||||
-- perform some random tests on bms_offset_members()
|
||||
SELECT test_random_offset_operations(NULL, 1000, 1024, 0) AS result;
|
||||
SELECT test_random_offset_operations(NULL, 1000, 0, 1024) AS result;
|
||||
|
||||
DROP EXTENSION test_bitmapset;
|
||||
|
||||
@@ -790,8 +790,8 @@ test_random_operations(PG_FUNCTION_ARGS)
|
||||
* Arguments:
|
||||
* arg1: optional random seed. NULL means use a random seed.
|
||||
* arg2: the number of operations to perform.
|
||||
* arg3: the maximum bitmapset member number to use in the random set.
|
||||
* arg4: the minimum bitmapset member number to use in the random set.
|
||||
* arg3: the minimum bitmapset member number to use in the random set.
|
||||
* arg4: the maximum bitmapset member number to use in the random set.
|
||||
*/
|
||||
Datum
|
||||
test_random_offset_operations(PG_FUNCTION_ARGS)
|
||||
@@ -799,27 +799,32 @@ test_random_offset_operations(PG_FUNCTION_ARGS)
|
||||
pg_prng_state state;
|
||||
int64 seed;
|
||||
int num_ops;
|
||||
int max_range;
|
||||
int min_value;
|
||||
int max_value;
|
||||
int member;
|
||||
uint32 range;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
seed = GetCurrentTimestamp();
|
||||
else
|
||||
seed = PG_GETARG_INT64(0);
|
||||
|
||||
num_ops = PG_GETARG_INT32(1);
|
||||
max_range = PG_GETARG_INT32(2);
|
||||
min_value = PG_GETARG_INT32(3);
|
||||
|
||||
if (PG_ARGISNULL(1) || num_ops <= 0)
|
||||
if (PG_ARGISNULL(1) || PG_GETARG_INT32(1) <= 0)
|
||||
elog(ERROR, "invalid number of operations");
|
||||
if (PG_ARGISNULL(2) || max_range <= 0)
|
||||
elog(ERROR, "invalid maximum range");
|
||||
if (PG_ARGISNULL(3) || min_value < 0)
|
||||
if (PG_ARGISNULL(2) || PG_GETARG_INT32(2) < 0)
|
||||
elog(ERROR, "invalid minimum value");
|
||||
if (PG_ARGISNULL(3) || PG_GETARG_INT32(3) < 0)
|
||||
elog(ERROR, "invalid maximum value");
|
||||
|
||||
num_ops = PG_GETARG_INT32(1);
|
||||
min_value = PG_GETARG_INT32(2);
|
||||
max_value = PG_GETARG_INT32(3);
|
||||
|
||||
if (max_value < min_value)
|
||||
elog(ERROR, "maximum value must be greater than or equal to minimum value");
|
||||
|
||||
pg_prng_seed(&state, (uint64) seed);
|
||||
range = (uint32) max_value - (uint32) min_value + 1;
|
||||
|
||||
for (int op = 0; op < num_ops; op++)
|
||||
{
|
||||
@@ -827,17 +832,29 @@ test_random_offset_operations(PG_FUNCTION_ARGS)
|
||||
Bitmapset *offset_bms1;
|
||||
Bitmapset *offset_bms2 = NULL;
|
||||
int offset;
|
||||
int nmembers;
|
||||
uint32 nmembers;
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/* Figure out a random offset and how many members to add */
|
||||
offset = (pg_prng_uint32(&state) % max_range) - (pg_prng_uint32(&state) % max_range);
|
||||
nmembers = pg_prng_uint32(&state) % max_range + min_value;
|
||||
/*
|
||||
* Choose a random offset for passing to bms_offset_members(). We
|
||||
* want a number between -max_value and max_value so we test both left
|
||||
* and right shifting and also test cases that push members,
|
||||
* occasionally all of them, off the bottom of the set.
|
||||
*/
|
||||
offset = (int) (pg_prng_uint32(&state) % ((uint32) max_value + 1));
|
||||
offset -= (int) (pg_prng_uint32(&state) % ((uint32) max_value + 1));
|
||||
|
||||
for (int i = 0; i < nmembers; i++)
|
||||
/* decide how many members to add */
|
||||
nmembers = pg_prng_uint32(&state) % range;
|
||||
|
||||
/*
|
||||
* Add a random number of members with values between the minimum and
|
||||
* maximum values.
|
||||
*/
|
||||
for (uint32 i = 0; i < nmembers; i++)
|
||||
{
|
||||
member = pg_prng_uint32(&state) % max_range + min_value;
|
||||
member = min_value + (pg_prng_uint32(&state) % range);
|
||||
random_bms = bms_add_member(random_bms, member);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user