Skip to content

Commit b5fd497

Browse files
committed
Fix yet more portability bugs in integerset and its tests.
There were more large constants that needed UINT64CONST. And one variable was declared as "int", when it needed to be uint64. These bugs were only visible on 32-bit systems; clearly I should've tested on one, given that this code does a lot of work with 64-bit integers. Also, in the test "huge distances" test, the code created some values with random distances between them, but the test logic didn't take into account the possibility that the random distance was exactly 1. That never actually happens with the seed we're using, but let's be tidy.
1 parent 638db07 commit b5fd497

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

src/backend/lib/integerset.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ static const struct
845845
* This value looks like a 0-mode codeword, but we check for it
846846
* specifically. (In a real 0-mode codeword, all the unused bits are zero.)
847847
*/
848-
#define EMPTY_CODEWORD (0xFFFFFFFFFFFFFFF0)
848+
#define EMPTY_CODEWORD UINT64CONST(0xFFFFFFFFFFFFFFF0)
849849

850850
/*
851851
* Encode a number of integers into a Simple-8b codeword.
@@ -885,7 +885,7 @@ simple8b_encode(uint64 *ints, int *num_encoded, uint64 base)
885885
i = 0;
886886
for (;;)
887887
{
888-
if (diff >= (1L << bits))
888+
if (diff >= (UINT64CONST(1) << bits))
889889
{
890890
/* too large, step up to next mode */
891891
selector++;
@@ -948,7 +948,7 @@ simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base)
948948
int selector = codeword & 0x0f;
949949
int nints = simple8b_modes[selector].num_ints;
950950
uint64 bits = simple8b_modes[selector].bits_per_int;
951-
uint64 mask = (1L << bits) - 1;
951+
uint64 mask = (UINT64CONST(1) << bits) - 1;
952952
uint64 prev_value;
953953

954954
if (codeword == EMPTY_CODEWORD)
@@ -961,7 +961,7 @@ simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base)
961961
{
962962
uint64 diff = codeword & mask;
963963

964-
decoded[i] = prev_value + 1L + diff;
964+
decoded[i] = prev_value + 1 + diff;
965965
prev_value = decoded[i];
966966
codeword >>= bits;
967967
}
@@ -992,7 +992,7 @@ simple8b_contains(uint64 codeword, uint64 key, uint64 base)
992992
}
993993
else
994994
{
995-
int mask = (1L << bits) - 1;
995+
uint64 mask = (UINT64CONST(1) << bits) - 1;
996996
uint64 prev_value;
997997

998998
prev_value = base;
@@ -1001,7 +1001,7 @@ simple8b_contains(uint64 codeword, uint64 key, uint64 base)
10011001
uint64 diff = codeword & mask;
10021002
uint64 curr_value;
10031003

1004-
curr_value = prev_value + 1L + diff;
1004+
curr_value = prev_value + 1 + diff;
10051005

10061006
if (curr_value >= key)
10071007
{

src/test/modules/test_integerset/test_integerset.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,21 +590,24 @@ test_huge_distances(void)
590590
for (int i = 0; i < num_values; i++)
591591
{
592592
uint64 x = values[i];
593+
bool expected;
593594
bool result;
594595

595596
if (x > 0)
596597
{
598+
expected = (values[i - 1] == x - 1);
597599
result = intset_is_member(intset, x - 1);
598-
if (result != false)
600+
if (result != expected)
599601
elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x - 1);
600602
}
601603

602604
result = intset_is_member(intset, x);
603605
if (result != true)
604606
elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x);
605607

608+
expected = (i != num_values - 1) ? (values[i + 1] == x + 1) : false;
606609
result = intset_is_member(intset, x + 1);
607-
if (result != false)
610+
if (result != expected)
608611
elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x + 1);
609612
}
610613

0 commit comments

Comments
 (0)