Fix yet more portability bugs in integerset and its tests.
authorHeikki Linnakangas <[email protected]>
Fri, 22 Mar 2019 15:59:19 +0000 (17:59 +0200)
committerHeikki Linnakangas <[email protected]>
Fri, 22 Mar 2019 15:59:19 +0000 (17:59 +0200)
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.

src/backend/lib/integerset.c
src/test/modules/test_integerset/test_integerset.c

index fcbb2bd0dbae53eeff107fb950b31aca8ed19e2a..74ed6215546e7400eea4ce88d2d14a551064ad34 100644 (file)
@@ -845,7 +845,7 @@ static const struct
  * This value looks like a 0-mode codeword,  but we check for it
  * specifically.  (In a real 0-mode codeword, all the unused bits are zero.)
  */
-#define EMPTY_CODEWORD         (0xFFFFFFFFFFFFFFF0)
+#define EMPTY_CODEWORD         UINT64CONST(0xFFFFFFFFFFFFFFF0)
 
 /*
  * Encode a number of integers into a Simple-8b codeword.
@@ -885,7 +885,7 @@ simple8b_encode(uint64 *ints, int *num_encoded, uint64 base)
        i = 0;
        for (;;)
        {
-               if (diff >= (1L << bits))
+               if (diff >= (UINT64CONST(1) << bits))
                {
                        /* too large, step up to next mode */
                        selector++;
@@ -948,7 +948,7 @@ simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base)
        int                     selector = codeword & 0x0f;
        int                     nints = simple8b_modes[selector].num_ints;
        uint64          bits = simple8b_modes[selector].bits_per_int;
-       uint64          mask = (1L << bits) - 1;
+       uint64          mask = (UINT64CONST(1) << bits) - 1;
        uint64          prev_value;
 
        if (codeword == EMPTY_CODEWORD)
@@ -961,7 +961,7 @@ simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base)
        {
                uint64          diff = codeword & mask;
 
-               decoded[i] = prev_value + 1L + diff;
+               decoded[i] = prev_value + 1 + diff;
                prev_value = decoded[i];
                codeword >>= bits;
        }
@@ -992,7 +992,7 @@ simple8b_contains(uint64 codeword, uint64 key, uint64 base)
        }
        else
        {
-               int                     mask = (1L << bits) - 1;
+               uint64          mask = (UINT64CONST(1) << bits) - 1;
                uint64          prev_value;
 
                prev_value = base;
@@ -1001,7 +1001,7 @@ simple8b_contains(uint64 codeword, uint64 key, uint64 base)
                        uint64          diff = codeword & mask;
                        uint64          curr_value;
 
-                       curr_value = prev_value + 1L + diff;
+                       curr_value = prev_value + 1 + diff;
 
                        if (curr_value >= key)
                        {
index 0bb6d47f4b167f44d30236df3c66b8e5647e07a1..32713f4baa1838c74cd0799958eb022ebbfe60e1 100644 (file)
@@ -590,12 +590,14 @@ test_huge_distances(void)
        for (int i = 0; i < num_values; i++)
        {
                uint64          x = values[i];
+               bool            expected;
                bool            result;
 
                if (x > 0)
                {
+                       expected = (values[i - 1] == x - 1);
                        result = intset_is_member(intset, x - 1);
-                       if (result != false)
+                       if (result != expected)
                                elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x - 1);
                }
 
@@ -603,8 +605,9 @@ test_huge_distances(void)
                if (result != true)
                        elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x);
 
+               expected = (i != num_values - 1) ? (values[i + 1] == x + 1) : false;
                result = intset_is_member(intset, x + 1);
-               if (result != false)
+               if (result != expected)
                        elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x + 1);
        }