LCOV - code coverage report
Current view: top level - src/test/modules/test_lfind - test_lfind.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 65 84 77.4 %
Date: 2024-11-21 10:14:43 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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             : 
      26           2 : PG_MODULE_MAGIC;
      27             : 
      28             : /* workhorse for test_lfind8 */
      29             : static void
      30          16 : test_lfind8_internal(uint8 key)
      31             : {
      32             :     uint8       charbuf[LEN_WITH_TAIL(Vector8)];
      33          16 :     const int   len_no_tail = LEN_NO_TAIL(Vector8);
      34          16 :     const int   len_with_tail = LEN_WITH_TAIL(Vector8);
      35             : 
      36          16 :     memset(charbuf, 0xFF, len_with_tail);
      37             :     /* search tail to test one-byte-at-a-time path */
      38          16 :     charbuf[len_with_tail - 1] = key;
      39          16 :     if (key > 0x00 && pg_lfind8(key - 1, charbuf, len_with_tail))
      40           0 :         elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key - 1);
      41          16 :     if (key < 0xFF && !pg_lfind8(key, charbuf, len_with_tail))
      42           0 :         elog(ERROR, "pg_lfind8() did not find existing element '0x%x'", key);
      43          16 :     if (key < 0xFE && pg_lfind8(key + 1, charbuf, len_with_tail))
      44           0 :         elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key + 1);
      45             : 
      46          16 :     memset(charbuf, 0xFF, len_with_tail);
      47             :     /* search with vector operations */
      48          16 :     charbuf[len_no_tail - 1] = key;
      49          16 :     if (key > 0x00 && pg_lfind8(key - 1, charbuf, len_no_tail))
      50           0 :         elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key - 1);
      51          16 :     if (key < 0xFF && !pg_lfind8(key, charbuf, len_no_tail))
      52           0 :         elog(ERROR, "pg_lfind8() did not find existing element '0x%x'", key);
      53          16 :     if (key < 0xFE && pg_lfind8(key + 1, charbuf, len_no_tail))
      54           0 :         elog(ERROR, "pg_lfind8() found nonexistent element '0x%x'", key + 1);
      55          16 : }
      56             : 
      57           4 : PG_FUNCTION_INFO_V1(test_lfind8);
      58             : Datum
      59           2 : test_lfind8(PG_FUNCTION_ARGS)
      60             : {
      61           2 :     test_lfind8_internal(0);
      62           2 :     test_lfind8_internal(1);
      63           2 :     test_lfind8_internal(0x7F);
      64           2 :     test_lfind8_internal(0x80);
      65           2 :     test_lfind8_internal(0x81);
      66           2 :     test_lfind8_internal(0xFD);
      67           2 :     test_lfind8_internal(0xFE);
      68           2 :     test_lfind8_internal(0xFF);
      69             : 
      70           2 :     PG_RETURN_VOID();
      71             : }
      72             : 
      73             : /* workhorse for test_lfind8_le */
      74             : static void
      75          16 : test_lfind8_le_internal(uint8 key)
      76             : {
      77             :     uint8       charbuf[LEN_WITH_TAIL(Vector8)];
      78          16 :     const int   len_no_tail = LEN_NO_TAIL(Vector8);
      79          16 :     const int   len_with_tail = LEN_WITH_TAIL(Vector8);
      80             : 
      81          16 :     memset(charbuf, 0xFF, len_with_tail);
      82             :     /* search tail to test one-byte-at-a-time path */
      83          16 :     charbuf[len_with_tail - 1] = key;
      84          16 :     if (key > 0x00 && pg_lfind8_le(key - 1, charbuf, len_with_tail))
      85           0 :         elog(ERROR, "pg_lfind8_le() found nonexistent element <= '0x%x'", key - 1);
      86          16 :     if (key < 0xFF && !pg_lfind8_le(key, charbuf, len_with_tail))
      87           0 :         elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key);
      88          16 :     if (key < 0xFE && !pg_lfind8_le(key + 1, charbuf, len_with_tail))
      89           0 :         elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key + 1);
      90             : 
      91          16 :     memset(charbuf, 0xFF, len_with_tail);
      92             :     /* search with vector operations */
      93          16 :     charbuf[len_no_tail - 1] = key;
      94          16 :     if (key > 0x00 && pg_lfind8_le(key - 1, charbuf, len_no_tail))
      95           0 :         elog(ERROR, "pg_lfind8_le() found nonexistent element <= '0x%x'", key - 1);
      96          16 :     if (key < 0xFF && !pg_lfind8_le(key, charbuf, len_no_tail))
      97           0 :         elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key);
      98          16 :     if (key < 0xFE && !pg_lfind8_le(key + 1, charbuf, len_no_tail))
      99           0 :         elog(ERROR, "pg_lfind8_le() did not find existing element <= '0x%x'", key + 1);
     100          16 : }
     101             : 
     102           4 : PG_FUNCTION_INFO_V1(test_lfind8_le);
     103             : Datum
     104           2 : test_lfind8_le(PG_FUNCTION_ARGS)
     105             : {
     106           2 :     test_lfind8_le_internal(0);
     107           2 :     test_lfind8_le_internal(1);
     108           2 :     test_lfind8_le_internal(0x7F);
     109           2 :     test_lfind8_le_internal(0x80);
     110           2 :     test_lfind8_le_internal(0x81);
     111           2 :     test_lfind8_le_internal(0xFD);
     112           2 :     test_lfind8_le_internal(0xFE);
     113           2 :     test_lfind8_le_internal(0xFF);
     114             : 
     115           2 :     PG_RETURN_VOID();
     116             : }
     117             : 
     118           4 : PG_FUNCTION_INFO_V1(test_lfind32);
     119             : Datum
     120           2 : test_lfind32(PG_FUNCTION_ARGS)
     121             : {
     122             : #define TEST_ARRAY_SIZE 135
     123           2 :     uint32      test_array[TEST_ARRAY_SIZE] = {0};
     124             : 
     125           2 :     test_array[8] = 1;
     126           2 :     test_array[64] = 2;
     127           2 :     test_array[TEST_ARRAY_SIZE - 1] = 3;
     128             : 
     129           2 :     if (pg_lfind32(1, test_array, 4))
     130           0 :         elog(ERROR, "pg_lfind32() found nonexistent element");
     131           2 :     if (!pg_lfind32(1, test_array, TEST_ARRAY_SIZE))
     132           0 :         elog(ERROR, "pg_lfind32() did not find existing element");
     133             : 
     134           2 :     if (pg_lfind32(2, test_array, 32))
     135           0 :         elog(ERROR, "pg_lfind32() found nonexistent element");
     136           2 :     if (!pg_lfind32(2, test_array, TEST_ARRAY_SIZE))
     137           0 :         elog(ERROR, "pg_lfind32() did not find existing element");
     138             : 
     139           2 :     if (pg_lfind32(3, test_array, 96))
     140           0 :         elog(ERROR, "pg_lfind32() found nonexistent element");
     141           2 :     if (!pg_lfind32(3, test_array, TEST_ARRAY_SIZE))
     142           0 :         elog(ERROR, "pg_lfind32() did not find existing element");
     143             : 
     144           2 :     if (pg_lfind32(4, test_array, TEST_ARRAY_SIZE))
     145           0 :         elog(ERROR, "pg_lfind32() found nonexistent element");
     146             : 
     147           2 :     PG_RETURN_VOID();
     148             : }

Generated by: LCOV version 1.14