Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Make binaryheap available to frontend code.
authorNathan Bossart <nathan@postgresql.org>
Mon, 18 Sep 2023 19:18:33 +0000 (12:18 -0700)
committerNathan Bossart <nathan@postgresql.org>
Mon, 18 Sep 2023 19:18:33 +0000 (12:18 -0700)
There are a couple of places in frontend code that could make use
of this simple binary heap implementation.  This commit makes
binaryheap usable in frontend code, much like commit 26aaf97b68 did
for StringInfo.  Like StringInfo, the header file is left in lib/
to reduce the likelihood of unnecessary breakage.

The frontend version of binaryheap exposes a void *-based API since
frontend code does not have access to the Datum definitions.  This
seemed like a better approach than switching all existing uses to
void * or making the Datum definitions available to frontend code.

Reviewed-by: Tom Lane, Alvaro Herrera
Discussion: https://postgr.es/m/3612876.1689443232%40sss.pgh.pa.us

src/backend/lib/Makefile
src/backend/lib/meson.build
src/common/Makefile
src/common/binaryheap.c [moved from src/backend/lib/binaryheap.c with 90% similarity]
src/common/meson.build
src/include/lib/binaryheap.h
src/tools/pgindent/typedefs.list

index 9dad31398aed0ef927e07ca25969d9793069f4d7..b6cefd9cca09457990a1f5fd3f6a2de741444c37 100644 (file)
@@ -13,7 +13,6 @@ top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
 OBJS = \
-   binaryheap.o \
    bipartite_match.o \
    bloomfilter.o \
    dshash.o \
index 974cab87763f2e70a2a91fbb93195c0bdd281406..b4e88f54ae2f9481b48256e95d8ea08c9e701360 100644 (file)
@@ -1,7 +1,6 @@
 # Copyright (c) 2022-2023, PostgreSQL Global Development Group
 
 backend_sources += files(
-  'binaryheap.c',
   'bipartite_match.c',
   'bloomfilter.c',
   'dshash.c',
index 113029bf7b91519746144f3a4d4a31a23c664714..cc5c54dcee4e8be5ce1c0bacb09492d2cf51ff2a 100644 (file)
@@ -48,6 +48,7 @@ LIBS += $(PTHREAD_LIBS)
 OBJS_COMMON = \
    archive.o \
    base64.o \
+   binaryheap.o \
    checksum_helper.o \
    compression.o \
    config_info.o \
similarity index 90%
rename from src/backend/lib/binaryheap.c
rename to src/common/binaryheap.c
index 1737546757852163fad2ce229e1830fa5ed56eda..39a8243a6d5a21df36d89a2da309341962d09709 100644 (file)
@@ -6,15 +6,22 @@
  * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   src/backend/lib/binaryheap.c
+ *   src/common/binaryheap.c
  *
  *-------------------------------------------------------------------------
  */
 
+#ifdef FRONTEND
+#include "postgres_fe.h"
+#else
 #include "postgres.h"
+#endif
 
 #include <math.h>
 
+#ifdef FRONTEND
+#include "common/logging.h"
+#endif
 #include "lib/binaryheap.h"
 
 static void sift_down(binaryheap *heap, int node_off);
@@ -34,7 +41,7 @@ binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
    int         sz;
    binaryheap *heap;
 
-   sz = offsetof(binaryheap, bh_nodes) + sizeof(Datum) * capacity;
+   sz = offsetof(binaryheap, bh_nodes) + sizeof(bh_node_type) * capacity;
    heap = (binaryheap *) palloc(sz);
    heap->bh_space = capacity;
    heap->bh_compare = compare;
@@ -106,10 +113,16 @@ parent_offset(int i)
  * afterwards.
  */
 void
-binaryheap_add_unordered(binaryheap *heap, Datum d)
+binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
 {
    if (heap->bh_size >= heap->bh_space)
+   {
+#ifdef FRONTEND
+       pg_fatal("out of binary heap slots");
+#else
        elog(ERROR, "out of binary heap slots");
+#endif
+   }
    heap->bh_has_heap_property = false;
    heap->bh_nodes[heap->bh_size] = d;
    heap->bh_size++;
@@ -138,10 +151,16 @@ binaryheap_build(binaryheap *heap)
  * the heap property.
  */
 void
-binaryheap_add(binaryheap *heap, Datum d)
+binaryheap_add(binaryheap *heap, bh_node_type d)
 {
    if (heap->bh_size >= heap->bh_space)
+   {
+#ifdef FRONTEND
+       pg_fatal("out of binary heap slots");
+#else
        elog(ERROR, "out of binary heap slots");
+#endif
+   }
    heap->bh_nodes[heap->bh_size] = d;
    heap->bh_size++;
    sift_up(heap, heap->bh_size - 1);
@@ -154,7 +173,7 @@ binaryheap_add(binaryheap *heap, Datum d)
  * without modifying the heap. The caller must ensure that this
  * routine is not used on an empty heap. Always O(1).
  */
-Datum
+bh_node_type
 binaryheap_first(binaryheap *heap)
 {
    Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property);
@@ -169,10 +188,10 @@ binaryheap_first(binaryheap *heap)
  * that this routine is not used on an empty heap. O(log n) worst
  * case.
  */
-Datum
+bh_node_type
 binaryheap_remove_first(binaryheap *heap)
 {
-   Datum       result;
+   bh_node_type result;
 
    Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property);
 
@@ -204,7 +223,7 @@ binaryheap_remove_first(binaryheap *heap)
  * sifting the new node down.
  */
 void
-binaryheap_replace_first(binaryheap *heap, Datum d)
+binaryheap_replace_first(binaryheap *heap, bh_node_type d)
 {
    Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property);
 
@@ -221,7 +240,7 @@ binaryheap_replace_first(binaryheap *heap, Datum d)
 static void
 sift_up(binaryheap *heap, int node_off)
 {
-   Datum       node_val = heap->bh_nodes[node_off];
+   bh_node_type node_val = heap->bh_nodes[node_off];
 
    /*
     * Within the loop, the node_off'th array entry is a "hole" that
@@ -232,7 +251,7 @@ sift_up(binaryheap *heap, int node_off)
    {
        int         cmp;
        int         parent_off;
-       Datum       parent_val;
+       bh_node_type parent_val;
 
        /*
         * If this node is smaller than its parent, the heap condition is
@@ -264,7 +283,7 @@ sift_up(binaryheap *heap, int node_off)
 static void
 sift_down(binaryheap *heap, int node_off)
 {
-   Datum       node_val = heap->bh_nodes[node_off];
+   bh_node_type node_val = heap->bh_nodes[node_off];
 
    /*
     * Within the loop, the node_off'th array entry is a "hole" that
index 53942a9a61c46047e7d86072a61c5ee21e9df9ca..3b97497d1a9f5e40283229d1e52107d66fd5053e 100644 (file)
@@ -3,6 +3,7 @@
 common_sources = files(
   'archive.c',
   'base64.c',
+  'binaryheap.c',
   'checksum_helper.c',
   'compression.c',
   'controldata_utils.c',
index 52f7b06b253e525c8610483c5fef03e7dab00c16..3647aeae657630b4d8b5b26f3ca7c63056c3b185 100644 (file)
 #ifndef BINARYHEAP_H
 #define BINARYHEAP_H
 
+/*
+ * We provide a Datum-based API for backend code and a void *-based API for
+ * frontend code (since the Datum definitions are not available to frontend
+ * code).  You should typically avoid using bh_node_type directly and instead
+ * use Datum or void * as appropriate.
+ */
+#ifdef FRONTEND
+typedef void *bh_node_type;
+#else
+typedef Datum bh_node_type;
+#endif
+
 /*
  * For a max-heap, the comparator must return <0 iff a < b, 0 iff a == b,
  * and >0 iff a > b.  For a min-heap, the conditions are reversed.
  */
-typedef int (*binaryheap_comparator) (Datum a, Datum b, void *arg);
+typedef int (*binaryheap_comparator) (bh_node_type a, bh_node_type b, void *arg);
 
 /*
  * binaryheap
@@ -34,7 +46,7 @@ typedef struct binaryheap
    bool        bh_has_heap_property;   /* debugging cross-check */
    binaryheap_comparator bh_compare;
    void       *bh_arg;
-   Datum       bh_nodes[FLEXIBLE_ARRAY_MEMBER];
+   bh_node_type bh_nodes[FLEXIBLE_ARRAY_MEMBER];
 } binaryheap;
 
 extern binaryheap *binaryheap_allocate(int capacity,
@@ -42,12 +54,12 @@ extern binaryheap *binaryheap_allocate(int capacity,
                                       void *arg);
 extern void binaryheap_reset(binaryheap *heap);
 extern void binaryheap_free(binaryheap *heap);
-extern void binaryheap_add_unordered(binaryheap *heap, Datum d);
+extern void binaryheap_add_unordered(binaryheap *heap, bh_node_type d);
 extern void binaryheap_build(binaryheap *heap);
-extern void binaryheap_add(binaryheap *heap, Datum d);
-extern Datum binaryheap_first(binaryheap *heap);
-extern Datum binaryheap_remove_first(binaryheap *heap);
-extern void binaryheap_replace_first(binaryheap *heap, Datum d);
+extern void binaryheap_add(binaryheap *heap, bh_node_type d);
+extern bh_node_type binaryheap_first(binaryheap *heap);
+extern bh_node_type binaryheap_remove_first(binaryheap *heap);
+extern void binaryheap_replace_first(binaryheap *heap, bh_node_type d);
 
 #define binaryheap_empty(h)            ((h)->bh_size == 0)
 
index f3d8a2a855ce05cc2c835eb9befcd64386d0c6b7..b5bbdd1608cfbaaf4edee8d86ebc05b7d758f581 100644 (file)
@@ -3198,6 +3198,7 @@ bbstreamer_tar_archiver
 bbstreamer_tar_parser
 bbstreamer_zstd_frame
 bgworker_main_type
+bh_node_type
 binaryheap
 binaryheap_comparator
 bitmapword