Age Owner Branch data TLA Line data Source code
1 : : /*--------------------------------------------------------------------------
2 : : *
3 : : * test_lfind.c
4 : : * Test correctness of optimized linear search functions.
5 : : *
6 : : * Copyright (c) 2022-2024, PostgreSQL Global Development Group
7 : : *
8 : : * IDENTIFICATION
9 : : * src/test/modules/test_lfind/test_lfind.c
10 : : *
11 : : * -------------------------------------------------------------------------
12 : : */
13 : :
14 : : #include "postgres.h"
15 : :
16 : : #include "fmgr.h"
17 : : #include "port/pg_lfind.h"
18 : :
19 : : /*
20 : : * Convenience macros for testing both vector and scalar operations. The 2x
21 : : * factor is to make sure iteration works
22 : : */
23 : : #define LEN_NO_TAIL(vectortype) (2 * sizeof(vectortype))
24 : : #define LEN_WITH_TAIL(vectortype) (LEN_NO_TAIL(vectortype) + 3)
25 : :
620 john.naylor@postgres 26 :CBC 1 : PG_MODULE_MAGIC;
27 : :
28 : : /* workhorse for test_lfind8 */
29 : : static void
603 30 : 8 : test_lfind8_internal(uint8 key)
31 : : {
32 : : uint8 charbuf[LEN_WITH_TAIL(Vector8)];
33 : 8 : const int len_no_tail = LEN_NO_TAIL(Vector8);
34 : 8 : const int len_with_tail = LEN_WITH_TAIL(Vector8);
35 : :
36 : 8 : memset(charbuf, 0xFF, len_with_tail);
37 : : /* search tail to test one-byte-at-a-time path */
38 : 8 : charbuf[len_with_tail - 1] = key;
39 [ + + - + ]: 8 : if (key > 0x00 && pg_lfind8(key - 1, charbuf, len_with_tail))
603 john.naylor@postgres 40 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key - 1);
603 john.naylor@postgres 41 [ + + - + ]:CBC 8 : if (key < 0xFF && !pg_lfind8(key, charbuf, len_with_tail))
603 john.naylor@postgres 42 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() did not find existing element '0x%x'", key);
603 john.naylor@postgres 43 [ + + - + ]:CBC 8 : if (key < 0xFE && pg_lfind8(key + 1, charbuf, len_with_tail))
603 john.naylor@postgres 44 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key + 1);
45 : :
603 john.naylor@postgres 46 :CBC 8 : memset(charbuf, 0xFF, len_with_tail);
47 : : /* search with vector operations */
48 : 8 : charbuf[len_no_tail - 1] = key;
49 [ + + - + ]: 8 : if (key > 0x00 && pg_lfind8(key - 1, charbuf, len_no_tail))
603 john.naylor@postgres 50 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key - 1);
603 john.naylor@postgres 51 [ + + - + ]:CBC 8 : if (key < 0xFF && !pg_lfind8(key, charbuf, len_no_tail))
603 john.naylor@postgres 52 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() did not find existing element '0x%x'", key);
603 john.naylor@postgres 53 [ + + - + ]:CBC 8 : if (key < 0xFE && pg_lfind8(key + 1, charbuf, len_no_tail))
603 john.naylor@postgres 54 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key + 1);
603 john.naylor@postgres 55 :CBC 8 : }
56 : :
57 : 2 : PG_FUNCTION_INFO_V1(test_lfind8);
58 : : Datum
59 : 1 : test_lfind8(PG_FUNCTION_ARGS)
60 : : {
61 : 1 : test_lfind8_internal(0);
62 : 1 : test_lfind8_internal(1);
63 : 1 : test_lfind8_internal(0x7F);
64 : 1 : test_lfind8_internal(0x80);
65 : 1 : test_lfind8_internal(0x81);
66 : 1 : test_lfind8_internal(0xFD);
67 : 1 : test_lfind8_internal(0xFE);
68 : 1 : test_lfind8_internal(0xFF);
69 : :
70 : 1 : PG_RETURN_VOID();
71 : : }
72 : :
73 : : /* workhorse for test_lfind8_le */
74 : : static void
75 : 8 : test_lfind8_le_internal(uint8 key)
76 : : {
77 : : uint8 charbuf[LEN_WITH_TAIL(Vector8)];
78 : 8 : const int len_no_tail = LEN_NO_TAIL(Vector8);
79 : 8 : const int len_with_tail = LEN_WITH_TAIL(Vector8);
80 : :
81 : 8 : memset(charbuf, 0xFF, len_with_tail);
82 : : /* search tail to test one-byte-at-a-time path */
83 : 8 : charbuf[len_with_tail - 1] = key;
84 [ + + - + ]: 8 : if (key > 0x00 && pg_lfind8_le(key - 1, charbuf, len_with_tail))
603 john.naylor@postgres 85 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() found nonexistent element <= '0x%x'", key - 1);
603 john.naylor@postgres 86 [ + + - + ]:CBC 8 : if (key < 0xFF && !pg_lfind8_le(key, charbuf, len_with_tail))
603 john.naylor@postgres 87 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key);
603 john.naylor@postgres 88 [ + + - + ]:CBC 8 : if (key < 0xFE && !pg_lfind8_le(key + 1, charbuf, len_with_tail))
603 john.naylor@postgres 89 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key + 1);
90 : :
603 john.naylor@postgres 91 :CBC 8 : memset(charbuf, 0xFF, len_with_tail);
92 : : /* search with vector operations */
93 : 8 : charbuf[len_no_tail - 1] = key;
94 [ + + - + ]: 8 : if (key > 0x00 && pg_lfind8_le(key - 1, charbuf, len_no_tail))
603 john.naylor@postgres 95 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() found nonexistent element <= '0x%x'", key - 1);
603 john.naylor@postgres 96 [ + + - + ]:CBC 8 : if (key < 0xFF && !pg_lfind8_le(key, charbuf, len_no_tail))
603 john.naylor@postgres 97 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key);
603 john.naylor@postgres 98 [ + + - + ]:CBC 8 : if (key < 0xFE && !pg_lfind8_le(key + 1, charbuf, len_no_tail))
603 john.naylor@postgres 99 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key + 1);
603 john.naylor@postgres 100 :CBC 8 : }
101 : :
102 : 2 : PG_FUNCTION_INFO_V1(test_lfind8_le);
103 : : Datum
104 : 1 : test_lfind8_le(PG_FUNCTION_ARGS)
105 : : {
106 : 1 : test_lfind8_le_internal(0);
107 : 1 : test_lfind8_le_internal(1);
108 : 1 : test_lfind8_le_internal(0x7F);
109 : 1 : test_lfind8_le_internal(0x80);
110 : 1 : test_lfind8_le_internal(0x81);
111 : 1 : test_lfind8_le_internal(0xFD);
112 : 1 : test_lfind8_le_internal(0xFE);
113 : 1 : test_lfind8_le_internal(0xFF);
114 : :
115 : 1 : PG_RETURN_VOID();
116 : : }
117 : :
118 : 2 : PG_FUNCTION_INFO_V1(test_lfind32);
119 : : Datum
120 : 1 : test_lfind32(PG_FUNCTION_ARGS)
121 : : {
122 : : #define TEST_ARRAY_SIZE 135
620 123 : 1 : uint32 test_array[TEST_ARRAY_SIZE] = {0};
124 : :
125 : 1 : test_array[8] = 1;
126 : 1 : test_array[64] = 2;
127 : 1 : test_array[TEST_ARRAY_SIZE - 1] = 3;
128 : :
129 [ - + ]: 1 : if (pg_lfind32(1, test_array, 4))
620 john.naylor@postgres 130 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() found nonexistent element");
620 john.naylor@postgres 131 [ - + ]:CBC 1 : if (!pg_lfind32(1, test_array, TEST_ARRAY_SIZE))
620 john.naylor@postgres 132 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() did not find existing element");
133 : :
620 john.naylor@postgres 134 [ - + ]:CBC 1 : if (pg_lfind32(2, test_array, 32))
620 john.naylor@postgres 135 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() found nonexistent element");
620 john.naylor@postgres 136 [ - + ]:CBC 1 : if (!pg_lfind32(2, test_array, TEST_ARRAY_SIZE))
620 john.naylor@postgres 137 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() did not find existing element");
138 : :
620 john.naylor@postgres 139 [ - + ]:CBC 1 : if (pg_lfind32(3, test_array, 96))
620 john.naylor@postgres 140 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() found nonexistent element");
620 john.naylor@postgres 141 [ - + ]:CBC 1 : if (!pg_lfind32(3, test_array, TEST_ARRAY_SIZE))
620 john.naylor@postgres 142 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() did not find existing element");
143 : :
620 john.naylor@postgres 144 [ - + ]:CBC 1 : if (pg_lfind32(4, test_array, TEST_ARRAY_SIZE))
620 john.naylor@postgres 145 [ # # ]:UBC 0 : elog(ERROR, "pg_lfind32() found nonexistent element");
146 : :
620 john.naylor@postgres 147 :CBC 1 : PG_RETURN_VOID();
148 : : }
|