]> granicus.if.org Git - postgresql/commitdiff
Support fls().
authorRobert Haas <rhaas@postgresql.org>
Tue, 7 Feb 2012 18:45:46 +0000 (13:45 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 7 Feb 2012 18:45:46 +0000 (13:45 -0500)
The immediate impetus for this is that Noah Misch's patch to elide
unnecessary table and index rebuilds when changing typmod for temporal
types uses it; and this is extracted from that patch, with some
further commentary by me.  But it seems logically separate from the
remainder of the patch, so I'm committing it separately; this is not
the first time someone has wanted fls() in the backend and probably
won't be the last.

If we end up using this in more performance-critical spots it may be
worthwhile to add some architecture-specific optimizations to our
src/port version of fls() - e.g. any x86 platform can implement this
using the assembly instruction BSRL.  But performance won't matter
a bit for assessing typmod changes, so I'm not worried about that
right now.

configure
configure.in
src/include/pg_config.h.in
src/include/port.h
src/port/fls.c [new file with mode: 0644]

index af4f9a3d2cdc8f98c48e7232a83816c9bee28e51..26f945ef65250f7d8a2d6aa84e8f64aaf68d6773 100755 (executable)
--- a/configure
+++ b/configure
@@ -20833,7 +20833,8 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
 
 
-for ac_func in crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul
+
+for ac_func in crypt fls getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
index 9cad43620cc1b52eceae63269043e9d5196988b8..da5b11a96f85c3bbbd88ce7056bb091c7542dfc4 100644 (file)
@@ -1335,7 +1335,7 @@ fi
 pgac_save_LIBS="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
 
-AC_REPLACE_FUNCS([crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul])
+AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul])
 
 case $host_os in
 
index db84f494ef7abd4f0a9596046108e6a66030b781..46c72245032c537825671ee36f5a720c1d8f9bc2 100644 (file)
 /* Define to 1 if you have the `fdatasync' function. */
 #undef HAVE_FDATASYNC
 
+/* Define to 1 if you have the `fls' function. */
+#undef HAVE_FLS
+
 /* Define to 1 if you have the `fpclass' function. */
 #undef HAVE_FPCLASS
 
index bec40c11612dbc7ceab5f305a0eff2d5ded3d88e..a5e80211b41f34d7e6214d9cd27186ca458766b4 100644 (file)
@@ -396,6 +396,10 @@ extern double pg_erand48(unsigned short xseed[3]);
 extern long pg_lrand48(void);
 extern void pg_srand48(long seed);
 
+#ifndef HAVE_FLS
+extern int fls(int mask);
+#endif
+
 #ifndef HAVE_FSEEKO
 #define fseeko(a, b, c) fseek(a, b, c)
 #define ftello(a)              ftell(a)
diff --git a/src/port/fls.c b/src/port/fls.c
new file mode 100644 (file)
index 0000000..6badc86
--- /dev/null
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * fls.c
+ *       finds the last (most significant) bit that is set
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ *       src/port/fls.c
+ *
+ * This file was taken from FreeBSD to provide an implementation of fls()
+ * for platforms that lack it.  Note that the operating system's version may
+ * be substantially more efficient thatn ours, since some platforms have an
+ * assembly instruction that does exactly this.
+ *
+ * The FreeBSD copyright terms follow.
+ */
+
+/*-
+ * Copyright (c) 1990, 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.
+ * 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 "c.h"
+
+/*
+ * Find Last Set bit
+ */
+int
+fls(int mask)
+{
+       int bit;
+
+       if (mask == 0)
+               return (0);
+       for (bit = 1; mask != 1; bit++)
+               mask = (unsigned int)mask >> 1;
+       return (bit);
+}