1/*--------------------------------------------------------------------------
4 * Test correctness of binary heap implementation.
6 * Copyright (c) 2025, PostgreSQL Global Development Group
9 * src/test/modules/test_binaryheap/test_binaryheap.c
11 * -------------------------------------------------------------------------
24 * Test binaryheap_comparator for max-heap of integers.
33 * Loops through all nodes and returns the maximum value.
47 * Generate a random permutation of the integers 0..size-1.
52 int *permutation = (
int *)
palloc(size *
sizeof(
int));
57 * This is the "inside-out" variant of the Fisher-Yates shuffle algorithm.
58 * Notionally, we append each new value to the array and then swap it with
59 * a randomly-chosen array element (possibly including itself, else we
60 * fail to generate permutations with the last integer last). The swap
61 * step can be optimized by combining it with the insertion.
63 for (
int i = 1;
i < size;
i++)
67 if (
j <
i)
/* avoid fetching undefined data if j=i */
68 permutation[
i] = permutation[
j];
76 * Ensure that the heap property holds for the given heap, i.e., each parent is
77 * greater than or equal to its children.
85 int right = 2 *
i + 2;
90 elog(
ERROR,
"parent node less than left child");
94 elog(
ERROR,
"parent node less than right child");
99 * Check correctness of basic operations.
112 for (
int i = 0;
i < size;
i++)
119 elog(
ERROR,
"heap empty after adding values");
121 elog(
ERROR,
"wrong size for heap after adding values");
124 elog(
ERROR,
"incorrect root node after adding values");
126 for (
int i = 0;
i < size;
i++)
131 if (actual != expected)
132 elog(
ERROR,
"incorrect root node after removing root");
137 elog(
ERROR,
"heap not empty after removing all nodes");
141 * Test building heap after unordered additions.
149 for (
int i = 0;
i < size;
i++)
153 elog(
ERROR,
"wrong size for heap after unordered additions");
160 * Test removing nodes.
170 for (
int i = 0;
i < size;
i++)
173 for (
int i = 0;
i < remove_count;
i++)
183 elog(
ERROR,
"wrong size after removing nodes");
187 * Test replacing the root node.
194 for (
int i = 0;
i < size;
i++)
198 * Replace root with a value smaller than everything in the heap.
204 * Replace root with a value in the middle of the heap.
210 * Replace root with a larger value than everything in the heap.
217 * Test duplicate values.
225 for (
int i = 0;
i < size;
i++)
228 for (
int i = 0;
i < size;
i++)
231 elog(
ERROR,
"unexpected value in heap with duplicates");
243 for (
int i = 0;
i < size;
i++)
249 elog(
ERROR,
"heap not empty after resetting");
253 * SQL-callable entry point to perform all tests.
260 static const int test_sizes[] = {1, 2, 3, 10, 100, 1000};
262 for (
int i = 0;
i <
sizeof(test_sizes) /
sizeof(
int);
i++)
264 int size = test_sizes[
i];
Datum idx(PG_FUNCTION_ARGS)
void binaryheap_remove_node(binaryheap *heap, int n)
void binaryheap_build(binaryheap *heap)
void binaryheap_replace_first(binaryheap *heap, bh_node_type d)
void binaryheap_reset(binaryheap *heap)
bh_node_type binaryheap_first(binaryheap *heap)
void binaryheap_add(binaryheap *heap, bh_node_type d)
bh_node_type binaryheap_remove_first(binaryheap *heap)
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
#define binaryheap_size(h)
#define binaryheap_empty(h)
#define binaryheap_get_node(h, n)
static int pg_cmp_s32(int32 a, int32 b)
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
pg_prng_state pg_global_prng_state
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
static int int_cmp(Datum a, Datum b, void *arg)
Datum test_binaryheap(PG_FUNCTION_ARGS)
static int * get_permutation(int size)
static void test_reset(int size)
static int get_max_from_heap(binaryheap *heap)
static void verify_heap_property(binaryheap *heap)
static void test_remove_node(int size)
static void test_build(int size)
static void test_duplicates(int size)
static void test_basic(int size)
static void test_replace_first(int size)
PG_FUNCTION_INFO_V1(test_binaryheap)