diff --git a/configure b/configure index 618763bd7204ed04ea0563c252b002815e54e4c6..18743ba3650406bf1d23e9268e6523ba89012a16 100755 --- a/configure +++ b/configure @@ -11902,6 +11902,13 @@ case $host_os in esac +# Set path of qsort for solaris, which has a very slow qsort in certain cases. +QSORT="" +case $host_os in + solaris*) DLLINIT='$(top_builddir)/src/backend/port/qsort.o' ;; +esac + + # On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; # this hackery with HPUXMATHLIB allows us to cope. HPUXMATHLIB="" @@ -17584,6 +17591,7 @@ s,@STRTOL@,$STRTOL,;t t s,@STRTOUL@,$STRTOUL,;t t s,@STRCASECMP@,$STRCASECMP,;t t s,@DLLINIT@,$DLLINIT,;t t +s,@QSORT@,$QSORT,;t t s,@HPUXMATHLIB@,$HPUXMATHLIB,;t t s,@HAVE_POSIX_SIGNALS@,$HAVE_POSIX_SIGNALS,;t t s,@MSGFMT@,$MSGFMT,;t t diff --git a/configure.in b/configure.in index 9fba297a17a92766e8c1cdf3af5965a67824b4e4..8650e126e86edde928b2eb44a93beb654968ff7d 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.192 2002/07/18 04:13:59 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.193 2002/07/19 17:35:09 momjian Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -932,6 +932,13 @@ case $host_os in esac AC_SUBST(DLLINIT) +# Set path of qsort for solaris, which has a very slow qsort in certain cases. +QSORT="" +case $host_os in + solaris*) DLLINIT='$(top_builddir)/src/backend/port/qsort.o' ;; +esac +AC_SUBST(QSORT) + # On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; # this hackery with HPUXMATHLIB allows us to cope. HPUXMATHLIB="" diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 698208bd01a3a679af126f5b68a09477491689ec..f3d04c1927393023ed08e0c3abae6ebf42bc37bc 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -1,5 +1,5 @@ # -*-makefile-*- -# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.150 2002/07/18 04:30:36 momjian Exp $ +# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.151 2002/07/19 17:35:10 momjian Exp $ #------------------------------------------------------------------------------ # All PostgreSQL makefiles include this file and use the variables it sets, @@ -352,6 +352,7 @@ INET_ATON = @INET_ATON@ ISINF = @ISINF@ MEMCMP = @MEMCMP@ MISSING_RANDOM = @MISSING_RANDOM@ +QSORT = @QSORT@ SNPRINTF = @SNPRINTF@ SRANDOM = @SRANDOM@ STRCASECMP = @STRCASECMP@ @@ -360,7 +361,7 @@ STRERROR = @STRERROR@ STRTOL = @STRTOL@ STRTOUL = @STRTOUL@ -# Used by the backend +# Not really standard libc functions, used by the backend. DLLINIT = @DLLINIT@ TAS = @TAS@ diff --git a/src/backend/port/Makefile b/src/backend/port/Makefile index 8ae3e54f8367a903053f675e3981414d467e02bf..2960526c5af28996a6e8439d6ea23b8a96799563 100644 --- a/src/backend/port/Makefile +++ b/src/backend/port/Makefile @@ -13,7 +13,7 @@ # be converted to Method 2. # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.16 2002/07/18 04:13:59 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.17 2002/07/19 17:35:11 momjian Exp $ # #------------------------------------------------------------------------- @@ -21,7 +21,11 @@ subdir = src/backend/port top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -OBJS=dynloader.o pg_sema.o pg_shmem.o +OBJS=$(GETHOSTNAME) $(GETRUSAGE) $(INET_ATON) $(ISINF) $(MEMCMP) \ + $(MISSING_RANDOM) $(QSORT) $(SNPRINTF) $(SRANDOM) $(STRCASECMP) \ + $(STRDUP) $(STRERROR) $(STRTOL) $(STRTOUL) + +OBJS+=dynloader.o pg_sema.o pg_shmem.o OBJS+=$(DLLINIT) diff --git a/src/port/Makefile b/src/port/Makefile index 77499ae03e766c4b6c90cb2664cee2f1cba384ce..b005143018ac64444e32e9def89c37b4a6128beb 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -7,7 +7,7 @@ # with broken/missing library files. # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/port/Makefile,v 1.1 2002/07/18 04:13:59 momjian Exp $ +# $Header: /cvsroot/pgsql/src/port/Makefile,v 1.2 2002/07/19 17:35:11 momjian Exp $ # #------------------------------------------------------------------------- @@ -15,9 +15,9 @@ subdir = src/port top_builddir = ../.. include $(top_builddir)/src/Makefile.global -OBJS=$(GETHOSTNAME) $(GETRUSAGE) $(INET_ATON) $(ISINF) $(MEMCMP) \ - $(MISSING_RANDOM) $(SNPRINTF) $(SRANDOM) $(STRCASECMP) $(STRDUP) \ - $(STRERROR) $(STRTOL) $(STRTOUL) -distclean clean: - rm -f $(OBJS) +# +# The backend/port directory removes these files. +# +#distclean clean: +# rm -f $(OBJS) diff --git a/src/port/qsort.c b/src/port/qsort.c new file mode 100644 index 0000000000000000000000000000000000000000..5562f603aa4c083486839e876b55a40d1ccfae36 --- /dev/null +++ b/src/port/qsort.c @@ -0,0 +1,208 @@ +/* + * Copied from NetBSD CVS, 2002-07-19, bjm + * Add do ... while() macro fix + * Remove __inline, _DIAGASSERTs + */ + +/* $NetBSD: qsort.c,v 1.12 1999/09/20 04:39:40 lukem Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 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. + */ + +#include <sys/cdefs.h> +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> + +static char *med3 __P((char *, char *, char *, + int (*) (const void *, const void *))); +static void swapfunc __P((char *, char *, size_t, int)); + +#define min(a, b) (a) < (b) ? a : b + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) \ +do { \ + size_t i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *)(void *)(parmi); \ + TYPE *pj = (TYPE *)(void *)(parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} while (0) + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static void +swapfunc(a, b, n, swaptype) +char *a, + *b; +size_t n; +int swaptype; +{ + if (swaptype <= 1) + swapcode(long, a, b, n); + else + swapcode(char, a, b, n); +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(void *)(a); \ + *(long *)(void *)(a) = *(long *)(void *)(b); \ + *(long *)(void *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype) + +static char * +med3(a, b, c, cmp) +char *a, + *b, + *c; +int (*cmp) __P((const void *, const void *)); +{ + return cmp(a, b) < 0 ? + (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a)) + : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c)); +} + +void +qsort(a, n, es, cmp) +void *a; +size_t n, + es; +int (*cmp) __P((const void *, const void *)); +{ + char *pa, + *pb, + *pc, + *pd, + *pl, + *pm, + *pn; + int d, + r, + swaptype, + swap_cnt; + +loop:SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) + { + for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) + for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *) a + (n / 2) * es; + if (n > 7) + { + pl = (char *) a; + pn = (char *) a + (n - 1) * es; + if (n > 40) + { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp); + pm = med3(pm - d, pm, pm + d, cmp); + pn = med3(pn - 2 * d, pn - d, pn, cmp); + } + pm = med3(pl, pm, pn, cmp); + } + swap(a, pm); + pa = pb = (char *) a + es; + + pc = pd = (char *) a + (n - 1) * es; + for (;;) + { + while (pb <= pc && (r = cmp(pb, a)) <= 0) + { + if (r == 0) + { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = cmp(pc, a)) >= 0) + { + if (r == 0) + { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) + { /* Switch to insertion sort */ + for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) + for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *) a + n * es; + r = min(pa - (char *) a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) + qsort(a, r / es, es, cmp); + if ((r = pd - pc) > es) + { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* qsort(pn - r, r / es, es, cmp);*/ +}