Move bsearch_arg to src/port
authorTomas Vondra <tomas.vondra@postgresql.org>
Mon, 22 Mar 2021 23:11:20 +0000 (00:11 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Mon, 22 Mar 2021 23:11:22 +0000 (00:11 +0100)
Until now the bsearch_arg function was used only in extended statistics
code, so it was defined in that code.  But we already have qsort_arg in
src/port, so let's move it next to it.

src/backend/statistics/extended_stats.c
src/include/port.h
src/include/statistics/extended_stats_internal.h
src/port/Makefile
src/port/bsearch_arg.c [new file with mode: 0644]
src/tools/msvc/Mkvcbuild.pm

index a030ea3653af554319af568e7ed664907c1b4316..fa42851fd519174d66f17f4279dbd8a69a394f1d 100644 (file)
@@ -659,37 +659,6 @@ compare_datums_simple(Datum a, Datum b, SortSupport ssup)
    return ApplySortComparator(a, false, b, false, ssup);
 }
 
-/* simple counterpart to qsort_arg */
-void *
-bsearch_arg(const void *key, const void *base, size_t nmemb, size_t size,
-           int (*compar) (const void *, const void *, void *),
-           void *arg)
-{
-   size_t      l,
-               u,
-               idx;
-   const void *p;
-   int         comparison;
-
-   l = 0;
-   u = nmemb;
-   while (l < u)
-   {
-       idx = (l + u) / 2;
-       p = (void *) (((const char *) base) + (idx * size));
-       comparison = (*compar) (key, p, arg);
-
-       if (comparison < 0)
-           u = idx;
-       else if (comparison > 0)
-           l = idx + 1;
-       else
-           return (void *) p;
-   }
-
-   return NULL;
-}
-
 /*
  * build_attnums_array
  *     Transforms a bitmap into an array of AttrNumber values.
index 227ef4b148263da1f5aa352ee794e7e64cddf62d..82f63de325058761c9d85fafd9569ef1656e8f89 100644 (file)
@@ -508,6 +508,11 @@ typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg);
 extern void qsort_arg(void *base, size_t nel, size_t elsize,
                      qsort_arg_comparator cmp, void *arg);
 
+extern void *bsearch_arg(const void *key, const void *base,
+                        size_t nmemb, size_t size,
+                        int (*compar) (const void *, const void *, void *),
+                        void *arg);
+
 /* port/chklocale.c */
 extern int pg_get_encoding_from_locale(const char *ctype, bool write_message);
 
index c849bd57c03abf17f1119cb9803f4d9c847c16e0..a0a3cf5b0fabc531794dc32e2f8f099ff8b5746e 100644 (file)
@@ -85,11 +85,6 @@ extern int   multi_sort_compare_dims(int start, int end, const SortItem *a,
 extern int compare_scalars_simple(const void *a, const void *b, void *arg);
 extern int compare_datums_simple(Datum a, Datum b, SortSupport ssup);
 
-extern void *bsearch_arg(const void *key, const void *base,
-                        size_t nmemb, size_t size,
-                        int (*compar) (const void *, const void *, void *),
-                        void *arg);
-
 extern AttrNumber *build_attnums_array(Bitmapset *attrs, int *numattrs);
 
 extern SortItem *build_sorted_items(int numrows, int *nitems, HeapTuple *rows,
index e41b005c4f1bf9cd77714f608d1d351483f905fa..52dbf5783f00aec620ba15b66df6b4017e0cfc6e 100644 (file)
@@ -40,6 +40,7 @@ LIBS += $(PTHREAD_LIBS)
 OBJS = \
    $(LIBOBJS) \
    $(PG_CRC32C_OBJS) \
+   bsearch_arg.o \
    chklocale.o \
    erand48.o \
    inet_net_ntop.o \
diff --git a/src/port/bsearch_arg.c b/src/port/bsearch_arg.c
new file mode 100644 (file)
index 0000000..0f1eaeb
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * bsearch_arg.c: bsearch variant with a user-supplied pointer
+ *
+ * Copyright (c) 2021, PostgreSQL Global Development Group
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * src/port/bsearch_arg.c
+ */
+
+#include "c.h"
+
+/*
+ * Perform a binary search.
+ *
+ * The code below is a bit sneaky.  After a comparison fails, we
+ * divide the work in half by moving either left or right. If lim
+ * is odd, moving left simply involves halving lim: e.g., when lim
+ * is 5 we look at item 2, so we change lim to 2 so that we will
+ * look at items 0 & 1.  If lim is even, the same applies.  If lim
+ * is odd, moving right again involes halving lim, this time moving
+ * the base up one item past p: e.g., when lim is 5 we change base
+ * to item 3 and make lim 2 so that we will look at items 3 and 4.
+ * If lim is even, however, we have to shrink it by one before
+ * halving: e.g., when lim is 4, we still looked at item 2, so we
+ * have to make lim 3, then halve, obtaining 1, so that we will only
+ * look at item 3.
+ */
+void *
+bsearch_arg(const void *key, const void *base0,
+           size_t nmemb, size_t size,
+           int (*compar) (const void *, const void *, void *),
+           void *arg)
+{
+   const char *base = (const char *) base0;
+   int         lim,
+               cmp;
+   const void *p;
+
+   for (lim = nmemb; lim != 0; lim >>= 1)
+   {
+       p = base + (lim >> 1) * size;
+       cmp = (*compar) (key, p, arg);
+       if (cmp == 0)
+           return (void *) p;
+       if (cmp > 0)
+       {                       /* key > p: move right */
+           base = (const char *) p + size;
+           lim--;
+       }                       /* else move left */
+   }
+   return (NULL);
+}
index a184404e2137b1c2228bad7e28c4d8ec2202a8bc..bc651851307edb4036080bde3778e474723a0d72 100644 (file)
@@ -103,7 +103,7 @@ sub mkvcbuild
      dirent.c dlopen.c getopt.c getopt_long.c link.c
      pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
      pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
-     pqsignal.c mkdtemp.c qsort.c qsort_arg.c quotes.c system.c
+     pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
      strerror.c tar.c thread.c
      win32env.c win32error.c win32security.c win32setlocale.c win32stat.c);