Changes:
authorBruce Momjian <bruce@momjian.us>
Wed, 11 Jun 2003 18:44:15 +0000 (18:44 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 11 Jun 2003 18:44:15 +0000 (18:44 +0000)
1 intarray: bugfix for int[]-int[] operation
2 intarray: split _int.c to several files (_int.c now is unused)
3 ntarray (gist__intbig_ops opclass): use special type for index storage
4 ltree (gist__ltree_ops opclass), intarray (gist__intbig_ops): optimize
GiST's
penalty and picksplit interface functions, now use Hemming distance.

Teodor Sigaev

contrib/intarray/Makefile
contrib/intarray/_int.c [deleted file]
contrib/intarray/_int.sql.in
contrib/intarray/expected/_int.out
contrib/ltree/_ltree_gist.c
contrib/ltree/ltree.h

index 7cb06da2ac8484c8fa19b14b36c305c25e299010..b7249a8b7c771acbc62bb1dbd195c84476a65315 100644 (file)
@@ -1,10 +1,11 @@
-# $Header: /cvsroot/pgsql/contrib/intarray/Makefile,v 1.8 2001/09/06 10:49:29 petere Exp $
+# $Header: /cvsroot/pgsql/contrib/intarray/Makefile,v 1.9 2003/06/11 18:44:14 momjian Exp $
 
 subdir = contrib/intarray
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
-MODULES = _int
+MODULE_big = _int
+OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o 
 DATA_built = _int.sql
 DOCS = README.intarray
 REGRESS = _int
diff --git a/contrib/intarray/_int.c b/contrib/intarray/_int.c
deleted file mode 100644 (file)
index eb42e41..0000000
+++ /dev/null
@@ -1,2693 +0,0 @@
-/******************************************************************************
-  This file contains routines that can be bound to a Postgres backend and
-  called by the backend in the process of processing queries.  The calling
-  format for these routines is dictated by Postgres architecture.
-******************************************************************************/
-
-/*
-#define BS_DEBUG
-#define GIST_DEBUG
-#define GIST_QUERY_DEBUG
-*/
-
-#include "postgres.h"
-
-#include <float.h>
-
-#include "access/gist.h"
-#include "access/itup.h"
-#include "access/rtree.h"
-#include "catalog/pg_type.h"
-#include "utils/elog.h"
-#include "utils/palloc.h"
-#include "utils/array.h"
-#include "utils/builtins.h"
-#include "storage/bufpage.h"
-#include "lib/stringinfo.h"
-
-/* number ranges for compression */
-#define MAXNUMRANGE 100
-
-#define max(a,b)       ((a) >  (b) ? (a) : (b))
-#define min(a,b)       ((a) <= (b) ? (a) : (b))
-#define abs(a)         ((a) <  (0) ? -(a) : (a))
-
-/* dimension of array */
-#define NDIM 1
-
-/*
- * flags for gist__int_ops, use ArrayType->flags
- * which is unused (see array.h)
- */
-#define LEAFKEY        (1<<31)
-#define ISLEAFKEY(x)   ( ((ArrayType*)(x))->flags & LEAFKEY )
-
-/* useful macros for accessing int4 arrays */
-#define ARRPTR(x)  ( (int4 *) ARR_DATA_PTR(x) )
-#define ARRNELEMS(x)  ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
-
-#define ARRISVOID(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : ( ( ARR_NDIM(x) ) ? (elog(ERROR,"Array is not one-dimensional: %d dimensions",ARRNELEMS( x )),1) : 0 )  ) : 0 )
-
-#define SORT(x) \
-   do { \
-        if ( ARRNELEMS( x ) > 1 ) \
-           isort( ARRPTR( x ), ARRNELEMS( x ) ); \
-   } while(0)
-
-#define PREPAREARR(x) \
-   do { \
-        if ( ARRNELEMS( x ) > 1 ) \
-           if ( isort( ARRPTR( x ), ARRNELEMS( x ) ) ) \
-               x = _int_unique( x ); \
-   } while(0)
-
-/* "wish" function */
-#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
-
-
-/* bigint defines */
-#define BITBYTE 8
-#define SIGLENINT  64          /* >122 => key will toast, so very slow!!! */
-#define SIGLEN ( sizeof(int)*SIGLENINT )
-#define SIGLENBIT (SIGLEN*BITBYTE)
-
-typedef char BITVEC[SIGLEN];
-typedef char *BITVECP;
-
-#define SIGPTR(x)  ( (BITVECP) ARR_DATA_PTR(x) )
-
-
-#define LOOPBYTE(a) \
-       for(i=0;i<SIGLEN;i++) {\
-               a;\
-       }
-
-#define LOOPBIT(a) \
-       for(i=0;i<SIGLENBIT;i++) {\
-               a;\
-       }
-
-/* beware of multiple evaluation of arguments to these macros! */
-#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
-#define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 )
-#define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
-#define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITBYTE ) )
-#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 )
-#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
-#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
-
-
-#ifdef GIST_DEBUG
-static void
-printarr(ArrayType *a, int num)
-{
-   StringInfoData bbb;
-   char       *cur;
-   int         l;
-   int        *d;
-
-   d = ARRPTR(a);
-   initStringInfo(&bbb);
-   for (l = 0; l < min(num, ARRNELEMS(a)); l++)
-       appendStringInfo(&bbb, "%d ", d[l]);
-   elog(DEBUG4, "\t\t%s", bbb.data);
-   pfree(bbb.data);
-}
-static void
-printbitvec(BITVEC bv)
-{
-   int         i;
-   char        str[SIGLENBIT + 1];
-
-   str[SIGLENBIT] = '\0';
-   LOOPBIT(str[i] = (GETBIT(bv, i)) ? '1' : '0');
-
-   elog(DEBUG4, "BV: %s", str);
-}
-#endif
-
-/*
-** types for functions
-*/
-typedef ArrayType *(*formarray) (ArrayType *, ArrayType *);
-typedef void (*formfloat) (ArrayType *, float *);
-
-/*
-** useful function
-*/
-static bool isort(int4 *a, const int len);
-static ArrayType *new_intArrayType(int num);
-static ArrayType *copy_intArrayType(ArrayType *a);
-static ArrayType *resize_intArrayType(ArrayType *a, int num);
-static int internal_size(int *a, int len);
-static ArrayType *_int_unique(ArrayType *a);
-
-/* common GiST function*/
-static GIST_SPLITVEC *_int_common_picksplit(bytea *entryvec,
-                     GIST_SPLITVEC *v,
-                     formarray unionf,
-                     formarray interf,
-                     formfloat sizef,
-                     float coef);
-static float *_int_common_penalty(GISTENTRY *origentry,
-                   GISTENTRY *newentry,
-                   float *result,
-                   formarray unionf,
-                   formfloat sizef);
-static ArrayType *_int_common_union(bytea *entryvec,
-                 int *sizep,
-                 formarray unionf);
-
-/*
-** GiST support methods
-*/
-PG_FUNCTION_INFO_V1(g_int_consistent);
-PG_FUNCTION_INFO_V1(g_int_compress);
-PG_FUNCTION_INFO_V1(g_int_decompress);
-PG_FUNCTION_INFO_V1(g_int_penalty);
-PG_FUNCTION_INFO_V1(g_int_picksplit);
-PG_FUNCTION_INFO_V1(g_int_union);
-PG_FUNCTION_INFO_V1(g_int_same);
-
-Datum      g_int_consistent(PG_FUNCTION_ARGS);
-Datum      g_int_compress(PG_FUNCTION_ARGS);
-Datum      g_int_decompress(PG_FUNCTION_ARGS);
-Datum      g_int_penalty(PG_FUNCTION_ARGS);
-Datum      g_int_picksplit(PG_FUNCTION_ARGS);
-Datum      g_int_union(PG_FUNCTION_ARGS);
-Datum      g_int_same(PG_FUNCTION_ARGS);
-
-
-/*
-** R-tree support functions
-*/
-static bool inner_int_contains(ArrayType *a, ArrayType *b);
-static bool inner_int_overlap(ArrayType *a, ArrayType *b);
-static ArrayType *inner_int_union(ArrayType *a, ArrayType *b);
-static ArrayType *inner_int_inter(ArrayType *a, ArrayType *b);
-static void rt__int_size(ArrayType *a, float *sz);
-
-PG_FUNCTION_INFO_V1(_int_different);
-PG_FUNCTION_INFO_V1(_int_same);
-PG_FUNCTION_INFO_V1(_int_contains);
-PG_FUNCTION_INFO_V1(_int_contained);
-PG_FUNCTION_INFO_V1(_int_overlap);
-PG_FUNCTION_INFO_V1(_int_union);
-PG_FUNCTION_INFO_V1(_int_inter);
-
-Datum      _int_different(PG_FUNCTION_ARGS);
-Datum      _int_same(PG_FUNCTION_ARGS);
-Datum      _int_contains(PG_FUNCTION_ARGS);
-Datum      _int_contained(PG_FUNCTION_ARGS);
-Datum      _int_overlap(PG_FUNCTION_ARGS);
-Datum      _int_union(PG_FUNCTION_ARGS);
-Datum      _int_inter(PG_FUNCTION_ARGS);
-
-/*
-** _intbig methods
-*/
-PG_FUNCTION_INFO_V1(g_intbig_consistent);
-PG_FUNCTION_INFO_V1(g_intbig_compress);
-PG_FUNCTION_INFO_V1(g_intbig_decompress);
-PG_FUNCTION_INFO_V1(g_intbig_penalty);
-PG_FUNCTION_INFO_V1(g_intbig_picksplit);
-PG_FUNCTION_INFO_V1(g_intbig_union);
-PG_FUNCTION_INFO_V1(g_intbig_same);
-
-Datum      g_intbig_consistent(PG_FUNCTION_ARGS);
-Datum      g_intbig_compress(PG_FUNCTION_ARGS);
-Datum      g_intbig_decompress(PG_FUNCTION_ARGS);
-Datum      g_intbig_penalty(PG_FUNCTION_ARGS);
-Datum      g_intbig_picksplit(PG_FUNCTION_ARGS);
-Datum      g_intbig_union(PG_FUNCTION_ARGS);
-Datum      g_intbig_same(PG_FUNCTION_ARGS);
-
-static bool _intbig_contains(ArrayType *a, ArrayType *b);
-static bool _intbig_overlap(ArrayType *a, ArrayType *b);
-static ArrayType *_intbig_union(ArrayType *a, ArrayType *b);
-
-static ArrayType *_intbig_inter(ArrayType *a, ArrayType *b);
-static void rt__intbig_size(ArrayType *a, float *sz);
-
-
-
-/*****************************************************************************
- *         Boolean Search
- *****************************************************************************/
-
-#define BooleanSearchStrategy  20
-
-/*
- * item in polish notation with back link
- * to left operand
- */
-typedef struct ITEM
-{
-   int2        type;
-   int2        left;
-   int4        val;
-}  ITEM;
-
-typedef struct
-{
-   int4        len;
-   int4        size;
-   char        data[1];
-}  QUERYTYPE;
-
-#define HDRSIZEQT  ( 2*sizeof(int4) )
-#define COMPUTESIZE(size)  ( HDRSIZEQT + size * sizeof(ITEM) )
-#define GETQUERY(x)  (ITEM*)( (char*)(x)+HDRSIZEQT )
-
-PG_FUNCTION_INFO_V1(bqarr_in);
-PG_FUNCTION_INFO_V1(bqarr_out);
-Datum      bqarr_in(PG_FUNCTION_ARGS);
-Datum      bqarr_out(PG_FUNCTION_ARGS);
-
-PG_FUNCTION_INFO_V1(boolop);
-Datum      boolop(PG_FUNCTION_ARGS);
-
-PG_FUNCTION_INFO_V1(rboolop);
-Datum      rboolop(PG_FUNCTION_ARGS);
-
-PG_FUNCTION_INFO_V1(querytree);
-Datum      querytree(PG_FUNCTION_ARGS);
-
-static bool signconsistent(QUERYTYPE * query, BITVEC sign, bool leaf);
-static bool execconsistent(QUERYTYPE * query, ArrayType *array, bool leaf);
-
-/*****************************************************************************
- *                        GiST functions
- *****************************************************************************/
-
-/*
-** The GiST Consistent method for _intments
-** Should return false if for all data items x below entry,
-** the predicate x op query == FALSE, where op is the oper
-** corresponding to strategy in the pg_amop table.
-*/
-Datum
-g_int_consistent(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   ArrayType  *query = (ArrayType *) PG_GETARG_POINTER(1);
-   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
-   bool        retval;
-
-   if (strategy == BooleanSearchStrategy)
-       PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query,
-                              (ArrayType *) DatumGetPointer(entry->key),
-                 ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))));
-
-   /* XXX are we sure it's safe to scribble on the query object here? */
-   /* XXX what about toasted input? */
-   /* sort query for fast search, key is already sorted */
-   if (ARRISVOID(query))
-       PG_RETURN_BOOL(false);
-   PREPAREARR(query);
-
-   switch (strategy)
-   {
-       case RTOverlapStrategyNumber:
-           retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
-                                      query);
-           break;
-       case RTSameStrategyNumber:
-           if (GIST_LEAF(entry))
-               DirectFunctionCall3(
-                                   g_int_same,
-                                   entry->key,
-                                   PointerGetDatum(query),
-                                   PointerGetDatum(&retval)
-                   );
-           else
-               retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
-                                           query);
-           break;
-       case RTContainsStrategyNumber:
-           retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
-                                       query);
-           break;
-       case RTContainedByStrategyNumber:
-           if (GIST_LEAF(entry))
-               retval = inner_int_contains(query,
-                             (ArrayType *) DatumGetPointer(entry->key));
-           else
-               retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
-                                          query);
-           break;
-       default:
-           retval = FALSE;
-   }
-   PG_RETURN_BOOL(retval);
-}
-
-Datum
-g_int_union(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_union(
-                                       (bytea *) PG_GETARG_POINTER(0),
-                                       (int *) PG_GETARG_POINTER(1),
-                                       inner_int_union
-                                       ));
-}
-
-/*
-** GiST Compress and Decompress methods
-*/
-Datum
-g_int_compress(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   GISTENTRY  *retval;
-   ArrayType  *r;
-   int         len;
-   int        *dr;
-   int         i,
-               min,
-               cand;
-
-   if (entry->leafkey)
-   {
-       r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
-       PREPAREARR(r);
-       r->flags |= LEAFKEY;
-       retval = palloc(sizeof(GISTENTRY));
-       gistentryinit(*retval, PointerGetDatum(r),
-             entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-
-       PG_RETURN_POINTER(retval);
-   }
-
-   r = (ArrayType *) PG_DETOAST_DATUM(entry->key);
-   if (ISLEAFKEY(r) || ARRISVOID(r))
-   {
-       if (r != (ArrayType *) DatumGetPointer(entry->key))
-           pfree(r);
-       PG_RETURN_POINTER(entry);
-   }
-
-   if ((len = ARRNELEMS(r)) >= 2 * MAXNUMRANGE)
-   {                           /* compress */
-       if (r == (ArrayType *) DatumGetPointer(entry->key))
-           r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
-       r = resize_intArrayType(r, 2 * (len));
-
-       dr = ARRPTR(r);
-
-       for (i = len - 1; i >= 0; i--)
-           dr[2 * i] = dr[2 * i + 1] = dr[i];
-
-       len *= 2;
-       cand = 1;
-       while (len > MAXNUMRANGE * 2)
-       {
-           min = 0x7fffffff;
-           for (i = 2; i < len; i += 2)
-               if (min > (dr[i] - dr[i - 1]))
-               {
-                   min = (dr[i] - dr[i - 1]);
-                   cand = i;
-               }
-           memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int));
-           len -= 2;
-       }
-       r = resize_intArrayType(r, len);
-       retval = palloc(sizeof(GISTENTRY));
-       gistentryinit(*retval, PointerGetDatum(r),
-             entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-       PG_RETURN_POINTER(retval);
-   }
-   else
-       PG_RETURN_POINTER(entry);
-
-   PG_RETURN_POINTER(entry);
-}
-
-Datum
-g_int_decompress(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   GISTENTRY  *retval;
-   ArrayType  *r;
-   int        *dr,
-               lenr;
-   ArrayType  *in;
-   int         lenin;
-   int        *din;
-   int         i,
-               j;
-
-   in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
-
-   if (ARRISVOID(in))
-       PG_RETURN_POINTER(entry);
-
-   lenin = ARRNELEMS(in);
-
-   if (lenin < 2 * MAXNUMRANGE || ISLEAFKEY(in))
-   {                           /* not compressed value */
-       if (in != (ArrayType *) DatumGetPointer(entry->key))
-       {
-           retval = palloc(sizeof(GISTENTRY));
-           gistentryinit(*retval, PointerGetDatum(in),
-            entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE);
-
-           PG_RETURN_POINTER(retval);
-       }
-       PG_RETURN_POINTER(entry);
-   }
-
-   din = ARRPTR(in);
-   lenr = internal_size(din, lenin);
-
-   r = new_intArrayType(lenr);
-   dr = ARRPTR(r);
-
-   for (i = 0; i < lenin; i += 2)
-       for (j = din[i]; j <= din[i + 1]; j++)
-           if ((!i) || *(dr - 1) != j)
-               *dr++ = j;
-
-   if (in != (ArrayType *) DatumGetPointer(entry->key))
-       pfree(in);
-   retval = palloc(sizeof(GISTENTRY));
-   gistentryinit(*retval, PointerGetDatum(r),
-             entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-
-   PG_RETURN_POINTER(retval);
-}
-
-/*
-** The GiST Penalty method for _intments
-*/
-Datum
-g_int_penalty(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_penalty(
-                                     (GISTENTRY *) PG_GETARG_POINTER(0),
-                                     (GISTENTRY *) PG_GETARG_POINTER(1),
-                                         (float *) PG_GETARG_POINTER(2),
-                                         inner_int_union, rt__int_size
-                                         ));
-}
-
-
-Datum
-g_int_picksplit(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_picksplit(
-                                         (bytea *) PG_GETARG_POINTER(0),
-                                 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-                                           inner_int_union,
-                                           inner_int_inter,
-                                           rt__int_size,
-                                           0.01
-                                           ));
-}
-
-/*
-** Equality methods
-*/
-
-
-Datum
-g_int_same(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) PointerGetDatum(PG_GETARG_POINTER(0));
-   ArrayType  *b = (ArrayType *) PointerGetDatum(PG_GETARG_POINTER(1));
-   bool       *result = (bool *) PG_GETARG_POINTER(2);
-   int4        n = ARRNELEMS(a);
-   int4       *da,
-              *db;
-
-   if (n != ARRNELEMS(b))
-   {
-       *result = false;
-       PG_RETURN_POINTER(result);
-   }
-   *result = TRUE;
-   da = ARRPTR(a);
-   db = ARRPTR(b);
-   while (n--)
-       if (*da++ != *db++)
-       {
-           *result = FALSE;
-           break;
-       }
-
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-_int_contained(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_BOOL(DatumGetBool(
-                               DirectFunctionCall2(
-                                                   _int_contains,
-                                  PointerGetDatum(PG_GETARG_POINTER(1)),
-                                   PointerGetDatum(PG_GETARG_POINTER(0))
-                                                   )
-                               ));
-}
-
-Datum
-_int_contains(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   bool        res;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       return FALSE;
-
-   PREPAREARR(a);
-   PREPAREARR(b);
-   res = inner_int_contains(a, b);
-   pfree(a);
-   pfree(b);
-   PG_RETURN_BOOL(res);
-}
-
-static bool
-inner_int_contains(ArrayType *a, ArrayType *b)
-{
-   int         na,
-               nb;
-   int         i,
-               j,
-               n;
-   int        *da,
-              *db;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       return FALSE;
-
-   na = ARRNELEMS(a);
-   nb = ARRNELEMS(b);
-   da = ARRPTR(a);
-   db = ARRPTR(b);
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "contains %d %d", na, nb);
-#endif
-
-   i = j = n = 0;
-   while (i < na && j < nb)
-       if (da[i] < db[j])
-           i++;
-       else if (da[i] == db[j])
-       {
-           n++;
-           i++;
-           j++;
-       }
-       else
-           j++;
-
-   return (n == nb) ? TRUE : FALSE;
-}
-
-/*****************************************************************************
- * Operator class for R-tree indexing
- *****************************************************************************/
-
-Datum
-_int_different(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_BOOL(!DatumGetBool(
-                                DirectFunctionCall2(
-                                                    _int_same,
-                                  PointerGetDatum(PG_GETARG_POINTER(0)),
-                                   PointerGetDatum(PG_GETARG_POINTER(1))
-                                                    )
-                                ));
-}
-
-Datum
-_int_same(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   int         na,
-               nb;
-   int         n;
-   int        *da,
-              *db;
-   bool        result;
-   bool        avoid = ARRISVOID(a);
-   bool        bvoid = ARRISVOID(b);
-
-   if (avoid || bvoid)
-       return (avoid && bvoid) ? TRUE : FALSE;
-
-   SORT(a);
-   SORT(b);
-   na = ARRNELEMS(a);
-   nb = ARRNELEMS(b);
-   da = ARRPTR(a);
-   db = ARRPTR(b);
-
-   result = FALSE;
-
-   if (na == nb)
-   {
-       result = TRUE;
-       for (n = 0; n < na; n++)
-           if (da[n] != db[n])
-           {
-               result = FALSE;
-               break;
-           }
-   }
-
-   pfree(a);
-   pfree(b);
-
-   PG_RETURN_BOOL(result);
-}
-
-/* _int_overlap -- does a overlap b?
- */
-Datum
-_int_overlap(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   bool        result;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       return FALSE;
-
-   SORT(a);
-   SORT(b);
-
-   result = inner_int_overlap(a, b);
-
-   pfree(a);
-   pfree(b);
-
-   PG_RETURN_BOOL(result);
-}
-
-static bool
-inner_int_overlap(ArrayType *a, ArrayType *b)
-{
-   int         na,
-               nb;
-   int         i,
-               j;
-   int        *da,
-              *db;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       return FALSE;
-
-   na = ARRNELEMS(a);
-   nb = ARRNELEMS(b);
-   da = ARRPTR(a);
-   db = ARRPTR(b);
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "g_int_overlap");
-#endif
-
-   i = j = 0;
-   while (i < na && j < nb)
-       if (da[i] < db[j])
-           i++;
-       else if (da[i] == db[j])
-           return TRUE;
-       else
-           j++;
-
-   return FALSE;
-}
-
-Datum
-_int_union(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   ArrayType  *result;
-
-   if (!ARRISVOID(a))
-       SORT(a);
-   if (!ARRISVOID(b))
-       SORT(b);
-
-   result = inner_int_union(a, b);
-
-   if (a)
-       pfree(a);
-   if (b)
-       pfree(b);
-
-   PG_RETURN_POINTER(result);
-}
-
-static ArrayType *
-inner_int_union(ArrayType *a, ArrayType *b)
-{
-   ArrayType  *r = NULL;
-   int         na,
-               nb;
-   int        *da,
-              *db,
-              *dr;
-   int         i,
-               j;
-
-   if (ARRISVOID(a) && ARRISVOID(b))
-       return new_intArrayType(0);
-   if (ARRISVOID(a))
-       r = copy_intArrayType(b);
-   if (ARRISVOID(b))
-       r = copy_intArrayType(a);
-
-   if (r)
-       dr = ARRPTR(r);
-   else
-   {
-       na = ARRNELEMS(a);
-       nb = ARRNELEMS(b);
-       da = ARRPTR(a);
-       db = ARRPTR(b);
-
-       r = new_intArrayType(na + nb);
-       dr = ARRPTR(r);
-
-       /* union */
-       i = j = 0;
-       while (i < na && j < nb)
-           if (da[i] < db[j])
-               *dr++ = da[i++];
-           else
-               *dr++ = db[j++];
-
-       while (i < na)
-           *dr++ = da[i++];
-       while (j < nb)
-           *dr++ = db[j++];
-
-   }
-
-   if (ARRNELEMS(r) > 1)
-       r = _int_unique(r);
-
-   return r;
-}
-
-
-Datum
-_int_inter(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   ArrayType  *result;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       PG_RETURN_POINTER(new_intArrayType(0));
-
-   SORT(a);
-   SORT(b);
-
-   result = inner_int_inter(a, b);
-
-   pfree(a);
-   pfree(b);
-
-   PG_RETURN_POINTER(result);
-}
-
-static ArrayType *
-inner_int_inter(ArrayType *a, ArrayType *b)
-{
-   ArrayType  *r;
-   int         na,
-               nb;
-   int        *da,
-              *db,
-              *dr;
-   int         i,
-               j;
-
-   if (ARRISVOID(a) || ARRISVOID(b))
-       return new_intArrayType(0);
-
-   na = ARRNELEMS(a);
-   nb = ARRNELEMS(b);
-   da = ARRPTR(a);
-   db = ARRPTR(b);
-   r = new_intArrayType(min(na, nb));
-   dr = ARRPTR(r);
-
-   i = j = 0;
-   while (i < na && j < nb)
-       if (da[i] < db[j])
-           i++;
-       else if (da[i] == db[j])
-       {
-           if (i + j == 0 || (i + j > 0 && *(dr - 1) != db[j]))
-               *dr++ = db[j];
-           i++;
-           j++;
-       }
-       else
-           j++;
-
-   if ((dr - ARRPTR(r)) == 0)
-   {
-       pfree(r);
-       return new_intArrayType(0);
-   }
-   else
-       return resize_intArrayType(r, dr - ARRPTR(r));
-}
-
-static void
-rt__int_size(ArrayType *a, float *size)
-{
-   *size = (float) ARRNELEMS(a);
-
-   return;
-}
-
-
-/*****************************************************************************
- *                Miscellaneous operators and functions
- *****************************************************************************/
-
-/* len >= 2 */
-static bool
-isort(int4 *a, int len)
-{
-   int4        tmp,
-               index;
-   int4       *cur,
-              *end;
-   bool        r = FALSE;
-
-   end = a + len;
-   do
-   {
-       index = 0;
-       cur = a + 1;
-       while (cur < end)
-       {
-           if (*(cur - 1) > *cur)
-           {
-               tmp = *(cur - 1);
-               *(cur - 1) = *cur;
-               *cur = tmp;
-               index = 1;
-           }
-           else if (!r && *(cur - 1) == *cur)
-               r = TRUE;
-           cur++;
-       }
-   } while (index);
-   return r;
-}
-
-static ArrayType *
-new_intArrayType(int num)
-{
-   ArrayType  *r;
-   int         nbytes = ARR_OVERHEAD(NDIM) + sizeof(int) * num;
-
-   r = (ArrayType *) palloc0(nbytes);
-
-   ARR_SIZE(r) = nbytes;
-   ARR_NDIM(r) = NDIM;
-   ARR_ELEMTYPE(r) = INT4OID;
-   r->flags &= ~LEAFKEY;
-   *((int *) ARR_DIMS(r)) = num;
-   *((int *) ARR_LBOUND(r)) = 1;
-
-   return r;
-}
-
-static ArrayType *
-resize_intArrayType(ArrayType *a, int num)
-{
-   int         nbytes = ARR_OVERHEAD(NDIM) + sizeof(int) * num;
-
-   if (num == ARRNELEMS(a))
-       return a;
-
-   a = (ArrayType *) repalloc(a, nbytes);
-
-   a->size = nbytes;
-   *((int *) ARR_DIMS(a)) = num;
-   return a;
-}
-
-static ArrayType *
-copy_intArrayType(ArrayType *a)
-{
-   ArrayType  *r;
-
-   r = new_intArrayType(ARRNELEMS(a));
-   memmove(r, a, VARSIZE(a));
-   return r;
-}
-
-/* num for compressed key */
-static int
-internal_size(int *a, int len)
-{
-   int         i,
-               size = 0;
-
-   for (i = 0; i < len; i += 2)
-       if (!i || a[i] != a[i - 1])     /* do not count repeated range */
-           size += a[i + 1] - a[i] + 1;
-
-   return size;
-}
-
-#define UNIX_UNIQ(a) a = _int_unique(a)
-
-/* r is sorted and size of r > 1 */
-static ArrayType *
-_int_unique(ArrayType *r)
-{
-   int        *tmp,
-              *dr,
-              *data;
-   int         num = ARRNELEMS(r);
-
-   if ( num<2 )
-       return r;
-
-   data = tmp = dr = ARRPTR(r);
-   while (tmp - data < num)
-       if (*tmp != *dr)
-           *(++dr) = *tmp++;
-       else
-           tmp++;
-   return resize_intArrayType(r, dr + 1 - ARRPTR(r));
-}
-
-/*********************************************************************
-** intbig functions
-*********************************************************************/
-static void
-gensign(BITVEC sign, int *a, int len)
-{
-   int         i;
-
-   /* we assume that the sign vector is previously zeroed */
-   for (i = 0; i < len; i++)
-   {
-       HASH(sign, *a);
-       a++;
-   }
-}
-
-static bool
-_intbig_overlap(ArrayType *a, ArrayType *b)
-{
-   int         i;
-   BITVECP     da,
-               db;
-
-   da = SIGPTR(a);
-   db = SIGPTR(b);
-
-   LOOPBYTE(if (da[i] & db[i]) return TRUE);
-   return FALSE;
-}
-
-static bool
-_intbig_contains(ArrayType *a, ArrayType *b)
-{
-   int         i;
-   BITVECP     da,
-               db;
-
-   da = SIGPTR(a);
-   db = SIGPTR(b);
-
-   LOOPBYTE(if (db[i] & ~da[i]) return FALSE);
-
-   return TRUE;
-}
-
-static void
-rt__intbig_size(ArrayType *a, float *sz)
-{
-   int         i,
-               len = 0;
-   BITVECP     bv = SIGPTR(a);
-
-   LOOPBYTE(
-            len +=
-            GETBITBYTE(bv, 0) +
-            GETBITBYTE(bv, 1) +
-            GETBITBYTE(bv, 2) +
-            GETBITBYTE(bv, 3) +
-            GETBITBYTE(bv, 4) +
-            GETBITBYTE(bv, 5) +
-            GETBITBYTE(bv, 6) +
-            GETBITBYTE(bv, 7);
-   bv = (BITVECP) (((char *) bv) + 1);
-   );
-
-   *sz = (float) len;
-   return;
-}
-
-static ArrayType *
-_intbig_union(ArrayType *a, ArrayType *b)
-{
-   ArrayType  *r;
-   BITVECP     da,
-               db,
-               dr;
-   int         i;
-
-   r = new_intArrayType(SIGLENINT);
-
-   da = SIGPTR(a);
-   db = SIGPTR(b);
-   dr = SIGPTR(r);
-
-   LOOPBYTE(dr[i] = da[i] | db[i]);
-
-   return r;
-}
-
-static ArrayType *
-_intbig_inter(ArrayType *a, ArrayType *b)
-{
-   ArrayType  *r;
-   BITVECP     da,
-               db,
-               dr;
-   int         i;
-
-   r = new_intArrayType(SIGLENINT);
-
-   da = SIGPTR(a);
-   db = SIGPTR(b);
-   dr = SIGPTR(r);
-
-   LOOPBYTE(dr[i] = da[i] & db[i]);
-
-   return r;
-}
-
-Datum
-g_intbig_same(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) PG_GETARG_POINTER(0);
-   ArrayType  *b = (ArrayType *) PG_GETARG_POINTER(1);
-   bool       *result = (bool *) PG_GETARG_POINTER(2);
-   BITVECP     da,
-               db;
-   int         i;
-
-   da = SIGPTR(a);
-   db = SIGPTR(b);
-
-   LOOPBYTE(
-            if (da[i] != db[i])
-            {
-       *result = FALSE;
-       PG_RETURN_POINTER(result);
-   }
-   );
-
-   *result = TRUE;
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-g_intbig_compress(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   GISTENTRY  *retval;
-   ArrayType  *r,
-              *in;
-   bool        maycompress = true;
-   int         i;
-
-   if (DatumGetPointer(entry->key) != NULL)
-       in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
-   else
-       in = NULL;
-
-   if (!entry->leafkey)
-   {
-       LOOPBYTE(
-                if ((((char *) ARRPTR(in))[i] & 0xff) != 0xff)
-                {
-           maycompress = false;
-           break;
-       }
-       );
-       if (maycompress)
-       {
-           retval = palloc(sizeof(GISTENTRY));
-           r = new_intArrayType(1);
-           gistentryinit(*retval, PointerGetDatum(r),
-             entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-           PG_RETURN_POINTER(retval);
-       }
-       PG_RETURN_POINTER(entry);
-   }
-
-   retval = palloc(sizeof(GISTENTRY));
-   r = new_intArrayType(SIGLENINT);
-
-   if (ARRISVOID(in))
-   {
-       gistentryinit(*retval, PointerGetDatum(r),
-             entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-       if (in != (ArrayType *) DatumGetPointer(entry->key))
-           pfree(in);
-       PG_RETURN_POINTER(retval);
-   }
-
-   gensign(SIGPTR(r),
-           ARRPTR(in),
-           ARRNELEMS(in));
-
-   LOOPBYTE(
-            if ((((char *) ARRPTR(in))[i] & 0xff) != 0xff)
-            {
-       maycompress = false;
-       break;
-   }
-   );
-
-   if (maycompress)
-   {
-       pfree(r);
-       r = new_intArrayType(1);
-   }
-
-   gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
-
-   if (in != (ArrayType *) DatumGetPointer(entry->key))
-       pfree(in);
-
-   PG_RETURN_POINTER(retval);
-}
-
-Datum
-g_intbig_decompress(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   ArrayType  *key;
-
-   key = (ArrayType *) PG_DETOAST_DATUM(entry->key);
-
-   if (key != (ArrayType *) DatumGetPointer(entry->key))
-   {
-       GISTENTRY  *retval;
-
-       retval = palloc(sizeof(GISTENTRY));
-
-       gistentryinit(*retval, PointerGetDatum(key),
-                     entry->rel, entry->page, entry->offset, (key) ? VARSIZE(key) : 0, FALSE);
-       PG_RETURN_POINTER(retval);
-   }
-   if (ARRNELEMS(key) == 1)
-   {
-       GISTENTRY  *retval;
-       ArrayType  *newkey;
-
-       retval = palloc(sizeof(GISTENTRY));
-       newkey = new_intArrayType(SIGLENINT);
-       MemSet((void *) ARRPTR(newkey), 0xff, SIGLEN);
-
-       gistentryinit(*retval, PointerGetDatum(newkey),
-        entry->rel, entry->page, entry->offset, VARSIZE(newkey), FALSE);
-       PG_RETURN_POINTER(retval);
-   }
-   PG_RETURN_POINTER(entry);
-}
-
-Datum
-g_intbig_picksplit(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_picksplit(
-                                         (bytea *) PG_GETARG_POINTER(0),
-                                 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-                                           _intbig_union,
-                                           _intbig_inter,
-                                           rt__intbig_size,
-                                           0.1
-                                           ));
-}
-
-Datum
-g_intbig_union(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_union(
-                                       (bytea *) PG_GETARG_POINTER(0),
-                                       (int *) PG_GETARG_POINTER(1),
-                                       _intbig_union
-                                       ));
-}
-
-Datum
-g_intbig_penalty(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(_int_common_penalty(
-                                     (GISTENTRY *) PG_GETARG_POINTER(0),
-                                     (GISTENTRY *) PG_GETARG_POINTER(1),
-                                         (float *) PG_GETARG_POINTER(2),
-                                         _intbig_union, rt__intbig_size
-                                         ));
-}
-
-Datum
-g_intbig_consistent(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   ArrayType  *query = (ArrayType *) PG_GETARG_POINTER(1);
-   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
-   bool        retval;
-   ArrayType  *q;
-
-   if (strategy == BooleanSearchStrategy)
-       PG_RETURN_BOOL(signconsistent((QUERYTYPE *) query,
-                      SIGPTR((ArrayType *) DatumGetPointer(entry->key)),
-                                     false));
-
-   /* XXX what about toasted input? */
-   if (ARRISVOID(query))
-       return FALSE;
-
-   q = new_intArrayType(SIGLENINT);
-   gensign(SIGPTR(q),
-           ARRPTR(query),
-           ARRNELEMS(query));
-
-   switch (strategy)
-   {
-       case RTOverlapStrategyNumber:
-           retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q);
-           break;
-       case RTSameStrategyNumber:
-           if (GIST_LEAF(entry))
-               DirectFunctionCall3(
-                                   g_intbig_same,
-                                   entry->key,
-                                   PointerGetDatum(q),
-                                   PointerGetDatum(&retval)
-                   );
-           else
-               retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->key), q);
-           break;
-       case RTContainsStrategyNumber:
-           retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->key), q);
-           break;
-       case RTContainedByStrategyNumber:
-           retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q);
-           break;
-       default:
-           retval = FALSE;
-   }
-   pfree(q);
-   PG_RETURN_BOOL(retval);
-}
-
-/*****************************************************************
-** Common GiST Method
-*****************************************************************/
-
-/*
-** The GiST Union method for _intments
-** returns the minimal set that encloses all the entries in entryvec
-*/
-static ArrayType *
-_int_common_union(bytea *entryvec, int *sizep, formarray unionf)
-{
-   int         numranges,
-               i;
-   ArrayType  *out = (ArrayType *) NULL;
-   ArrayType  *tmp;
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "_int_common_union in");
-#endif
-
-   numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
-   tmp = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[0].key);
-
-   for (i = 1; i < numranges; i++)
-   {
-       out = (*unionf) (tmp, (ArrayType *)
-             DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key));
-       if (i > 1 && tmp)
-           pfree(tmp);
-       tmp = out;
-   }
-
-   out->flags &= ~LEAFKEY;
-   *sizep = VARSIZE(out);
-   if (*sizep == 0)
-   {
-       pfree(out);
-#ifdef GIST_DEBUG
-       elog(DEBUG4, "_int_common_union out1");
-#endif
-       return NULL;
-   }
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "_int_common_union out");
-#endif
-   return (out);
-
-}
-
-/*****************************************
- * The GiST Penalty method for _intments *
- *****************************************/
-
-static float *
-_int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
-                   formarray unionf,
-                   formfloat sizef)
-{
-   ArrayType  *ud;
-   float       tmp1,
-               tmp2;
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "penalty");
-#endif
-   ud = (*unionf) ((ArrayType *) DatumGetPointer(origentry->key),
-                   (ArrayType *) DatumGetPointer(newentry->key));
-   (*sizef) (ud, &tmp1);
-   (*sizef) ((ArrayType *) DatumGetPointer(origentry->key), &tmp2);
-   *result = tmp1 - tmp2;
-   pfree(ud);
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "--penalty\t%g", *result);
-#endif
-
-   return (result);
-}
-
-typedef struct
-{
-   OffsetNumber pos;
-   float       cost;
-} SPLITCOST;
-
-static int
-comparecost(const void *a, const void *b)
-{
-   if (((SPLITCOST *) a)->cost == ((SPLITCOST *) b)->cost)
-       return 0;
-   else
-       return (((SPLITCOST *) a)->cost > ((SPLITCOST *) b)->cost) ? 1 : -1;
-}
-
-/*
-** The GiST PickSplit method for _intments
-** We use Guttman's poly time split algorithm
-*/
-static GIST_SPLITVEC *
-_int_common_picksplit(bytea *entryvec,
-                     GIST_SPLITVEC *v,
-                     formarray unionf,
-                     formarray interf,
-                     formfloat sizef,
-                     float coef)
-{
-   OffsetNumber i,
-               j;
-   ArrayType  *datum_alpha,
-              *datum_beta;
-   ArrayType  *datum_l,
-              *datum_r;
-   ArrayType  *union_d,
-              *union_dl,
-              *union_dr;
-   ArrayType  *inter_d;
-   bool        firsttime;
-   float       size_alpha,
-               size_beta,
-               size_union,
-               size_inter;
-   float       size_waste,
-               waste;
-   float       size_l,
-               size_r;
-   int         nbytes;
-   OffsetNumber seed_1 = 0,
-               seed_2 = 0;
-   OffsetNumber *left,
-              *right;
-   OffsetNumber maxoff;
-   SPLITCOST  *costvector;
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "--------picksplit %d", (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY));
-#endif
-
-   maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 2;
-   nbytes = (maxoff + 2) * sizeof(OffsetNumber);
-   v->spl_left = (OffsetNumber *) palloc(nbytes);
-   v->spl_right = (OffsetNumber *) palloc(nbytes);
-
-   firsttime = true;
-   waste = 0.0;
-   for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
-   {
-       datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
-       for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
-       {
-           datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].key);
-
-           /* compute the wasted space by unioning these guys */
-           /* size_waste = size_union - size_inter; */
-           union_d = (*unionf) (datum_alpha, datum_beta);
-           (*sizef) (union_d, &size_union);
-           inter_d = (*interf) (datum_alpha, datum_beta);
-           (*sizef) (inter_d, &size_inter);
-           size_waste = size_union - size_inter;
-
-           pfree(union_d);
-
-           if (inter_d != (ArrayType *) NULL)
-               pfree(inter_d);
-
-           /*
-            * are these a more promising split that what we've already
-            * seen?
-            */
-
-           if (size_waste > waste || firsttime)
-           {
-               waste = size_waste;
-               seed_1 = i;
-               seed_2 = j;
-               firsttime = false;
-           }
-       }
-   }
-
-   left = v->spl_left;
-   v->spl_nleft = 0;
-   right = v->spl_right;
-   v->spl_nright = 0;
-   if (seed_1 == 0 || seed_2 == 0)
-   {
-       seed_1 = 1;
-       seed_2 = 2;
-   }
-
-   datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].key);
-   datum_l = copy_intArrayType(datum_alpha);
-   (*sizef) (datum_l, &size_l);
-   datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].key);
-   datum_r = copy_intArrayType(datum_beta);
-   (*sizef) (datum_r, &size_r);
-
-   maxoff = OffsetNumberNext(maxoff);
-
-   /*
-    * sort entries
-    */
-   costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
-   for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
-   {
-       costvector[i - 1].pos = i;
-       datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
-       union_d = (*unionf) (datum_l, datum_alpha);
-       (*sizef) (union_d, &size_alpha);
-       pfree(union_d);
-       union_d = (*unionf) (datum_r, datum_alpha);
-       (*sizef) (union_d, &size_beta);
-       pfree(union_d);
-       costvector[i - 1].cost = abs((size_alpha - size_l) - (size_beta - size_r));
-   }
-   qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
-
-   /*
-    * Now split up the regions between the two seeds.  An important
-    * property of this split algorithm is that the split vector v has the
-    * indices of items to be split in order in its left and right
-    * vectors.  We exploit this property by doing a merge in the code
-    * that actually splits the page.
-    *
-    * For efficiency, we also place the new index tuple in this loop. This
-    * is handled at the very end, when we have placed all the existing
-    * tuples and i == maxoff + 1.
-    */
-
-
-   for (j = 0; j < maxoff; j++)
-   {
-       i = costvector[j].pos;
-
-       /*
-        * If we've already decided where to place this item, just put it
-        * on the right list.  Otherwise, we need to figure out which page
-        * needs the least enlargement in order to store the item.
-        */
-
-       if (i == seed_1)
-       {
-           *left++ = i;
-           v->spl_nleft++;
-           continue;
-       }
-       else if (i == seed_2)
-       {
-           *right++ = i;
-           v->spl_nright++;
-           continue;
-       }
-
-       /* okay, which page needs least enlargement? */
-       datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key);
-       union_dl = (*unionf) (datum_l, datum_alpha);
-       union_dr = (*unionf) (datum_r, datum_alpha);
-       (*sizef) (union_dl, &size_alpha);
-       (*sizef) (union_dr, &size_beta);
-
-       /* pick which page to add it to */
-       if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, coef))
-       {
-           if (datum_l)
-               pfree(datum_l);
-           if (union_dr)
-               pfree(union_dr);
-           datum_l = union_dl;
-           size_l = size_alpha;
-           *left++ = i;
-           v->spl_nleft++;
-       }
-       else
-       {
-           if (datum_r)
-               pfree(datum_r);
-           if (union_dl)
-               pfree(union_dl);
-           datum_r = union_dr;
-           size_r = size_beta;
-           *right++ = i;
-           v->spl_nright++;
-       }
-   }
-   pfree(costvector);
-   *right = *left = FirstOffsetNumber;
-
-   datum_l->flags &= ~LEAFKEY;
-   datum_r->flags &= ~LEAFKEY;
-   v->spl_ldatum = PointerGetDatum(datum_l);
-   v->spl_rdatum = PointerGetDatum(datum_r);
-
-#ifdef GIST_DEBUG
-   elog(DEBUG4, "--------ENDpicksplit %d %d", v->spl_nleft, v->spl_nright);
-#endif
-   return v;
-}
-
-/*****************************************************************************
- *     BoolSearch
- *****************************************************************************/
-
-
-#define END        0
-#define ERR        1
-#define VAL        2
-#define OPR        3
-#define OPEN   4
-#define CLOSE  5
-
-/* parser's states */
-#define WAITOPERAND 1
-#define WAITENDOPERAND 2
-#define WAITOPERATOR   3
-
-/*
- * node of query tree, also used
- * for storing polish notation in parser
- */
-typedef struct NODE
-{
-   int4        type;
-   int4        val;
-   struct NODE *next;
-}  NODE;
-
-typedef struct
-{
-   char       *buf;
-   int4        state;
-   int4        count;
-   /* reverse polish notation in list (for temporary usage) */
-   NODE       *str;
-   /* number in str */
-   int4        num;
-}  WORKSTATE;
-
-/*
- * get token from query string
- */
-static int4
-gettoken(WORKSTATE * state, int4 *val)
-{
-   char        nnn[16],
-              *curnnn;
-
-   curnnn = nnn;
-   while (1)
-   {
-       switch (state->state)
-       {
-           case WAITOPERAND:
-               curnnn = nnn;
-               if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
-                   *(state->buf) == '-')
-               {
-                   state->state = WAITENDOPERAND;
-                   *curnnn = *(state->buf);
-                   curnnn++;
-               }
-               else if (*(state->buf) == '!')
-               {
-                   (state->buf)++;
-                   *val = (int4) '!';
-                   return OPR;
-               }
-               else if (*(state->buf) == '(')
-               {
-                   state->count++;
-                   (state->buf)++;
-                   return OPEN;
-               }
-               else if (*(state->buf) != ' ')
-                   return ERR;
-               break;
-           case WAITENDOPERAND:
-               if (*(state->buf) >= '0' && *(state->buf) <= '9')
-               {
-                   *curnnn = *(state->buf);
-                   curnnn++;
-               }
-               else
-               {
-                   *curnnn = '\0';
-                   *val = (int4) atoi(nnn);
-                   state->state = WAITOPERATOR;
-                   return (state->count && *(state->buf) == '\0')
-                       ? ERR : VAL;
-               }
-               break;
-           case WAITOPERATOR:
-               if (*(state->buf) == '&' || *(state->buf) == '|')
-               {
-                   state->state = WAITOPERAND;
-                   *val = (int4) *(state->buf);
-                   (state->buf)++;
-                   return OPR;
-               }
-               else if (*(state->buf) == ')')
-               {
-                   (state->buf)++;
-                   state->count--;
-                   return (state->count < 0) ? ERR : CLOSE;
-               }
-               else if (*(state->buf) == '\0')
-                   return (state->count) ? ERR : END;
-               else if (*(state->buf) != ' ')
-                   return ERR;
-               break;
-           default:
-               return ERR;
-               break;
-       }
-       (state->buf)++;
-   }
-   return END;
-}
-
-/*
- * push new one in polish notation reverse view
- */
-static void
-pushquery(WORKSTATE * state, int4 type, int4 val)
-{
-   NODE       *tmp = (NODE *) palloc(sizeof(NODE));
-
-   tmp->type = type;
-   tmp->val = val;
-   tmp->next = state->str;
-   state->str = tmp;
-   state->num++;
-}
-
-#define STACKDEPTH 16
-
-/*
- * make polish notation of query
- */
-static int4
-makepol(WORKSTATE * state)
-{
-   int4        val,
-               type;
-   int4        stack[STACKDEPTH];
-   int4        lenstack = 0;
-
-   while ((type = gettoken(state, &val)) != END)
-   {
-       switch (type)
-       {
-           case VAL:
-               pushquery(state, type, val);
-               while (lenstack && (stack[lenstack - 1] == (int4) '&' ||
-                                   stack[lenstack - 1] == (int4) '!'))
-               {
-                   lenstack--;
-                   pushquery(state, OPR, stack[lenstack]);
-               }
-               break;
-           case OPR:
-               if (lenstack && val == (int4) '|')
-                   pushquery(state, OPR, val);
-               else
-               {
-                   if (lenstack == STACKDEPTH)
-                       elog(ERROR, "Stack too short");
-                   stack[lenstack] = val;
-                   lenstack++;
-               }
-               break;
-           case OPEN:
-               if (makepol(state) == ERR)
-                   return ERR;
-               if (lenstack && (stack[lenstack - 1] == (int4) '&' ||
-                                stack[lenstack - 1] == (int4) '!'))
-               {
-                   lenstack--;
-                   pushquery(state, OPR, stack[lenstack]);
-               }
-               break;
-           case CLOSE:
-               while (lenstack)
-               {
-                   lenstack--;
-                   pushquery(state, OPR, stack[lenstack]);
-               };
-               return END;
-               break;
-           case ERR:
-           default:
-               elog(ERROR, "Syntax error");
-               return ERR;
-
-       }
-   }
-
-   while (lenstack)
-   {
-       lenstack--;
-       pushquery(state, OPR, stack[lenstack]);
-   };
-   return END;
-}
-
-typedef struct
-{
-   int4       *arrb;
-   int4       *arre;
-}  CHKVAL;
-
-/*
- * is there value 'val' in array or not ?
- */
-static bool
-checkcondition_arr(void *checkval, int4 val)
-{
-   int4       *StopLow = ((CHKVAL *) checkval)->arrb;
-   int4       *StopHigh = ((CHKVAL *) checkval)->arre;
-   int4       *StopMiddle;
-
-   /* Loop invariant: StopLow <= val < StopHigh */
-
-   while (StopLow < StopHigh)
-   {
-       StopMiddle = StopLow + (StopHigh - StopLow) / 2;
-       if (*StopMiddle == val)
-           return (true);
-       else if (*StopMiddle < val)
-           StopLow = StopMiddle + 1;
-       else
-           StopHigh = StopMiddle;
-   }
-   return false;
-}
-
-static bool
-checkcondition_bit(void *checkval, int4 val)
-{
-   return GETBIT(checkval, HASHVAL(val));
-}
-
-/*
- * check for boolean condition
- */
-static bool
-execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, int4 val))
-{
-
-   if (curitem->type == VAL)
-       return (*chkcond) (checkval, curitem->val);
-   else if (curitem->val == (int4) '!')
-   {
-       return (calcnot) ?
-           ((execute(curitem - 1, checkval, calcnot, chkcond)) ? false : true)
-           : true;
-   }
-   else if (curitem->val == (int4) '&')
-   {
-       if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
-           return execute(curitem - 1, checkval, calcnot, chkcond);
-       else
-           return false;
-   }
-   else
-   {                           /* |-operator */
-       if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
-           return true;
-       else
-           return execute(curitem - 1, checkval, calcnot, chkcond);
-   }
-   return false;
-}
-
-/*
- * signconsistent & execconsistent called by *_consistent
- */
-static bool
-signconsistent(QUERYTYPE * query, BITVEC sign, bool calcnot)
-{
-   return execute(
-                  GETQUERY(query) + query->size - 1,
-                  (void *) sign, calcnot,
-                  checkcondition_bit
-   );
-}
-
-static bool
-execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
-{
-   CHKVAL      chkval;
-
-   chkval.arrb = ARRPTR(array);
-   chkval.arre = chkval.arrb + ARRNELEMS(array);
-   return execute(
-                  GETQUERY(query) + query->size - 1,
-                  (void *) &chkval, calcnot,
-                  checkcondition_arr
-       );
-}
-
-/*
- * boolean operations
- */
-Datum
-rboolop(PG_FUNCTION_ARGS)
-{
-   return DirectFunctionCall2(
-                              boolop,
-                              PG_GETARG_DATUM(1),
-                              PG_GETARG_DATUM(0)
-   );
-}
-
-Datum
-boolop(PG_FUNCTION_ARGS)
-{
-   ArrayType  *val = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0));
-   QUERYTYPE  *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
-   CHKVAL      chkval;
-   bool        result;
-
-   if (ARRISVOID(val))
-   {
-       pfree(val);
-       PG_FREE_IF_COPY(query, 1);
-       PG_RETURN_BOOL(false);
-   }
-
-   PREPAREARR(val);
-   chkval.arrb = ARRPTR(val);
-   chkval.arre = chkval.arrb + ARRNELEMS(val);
-   result = execute(
-                    GETQUERY(query) + query->size - 1,
-                    &chkval, true,
-                    checkcondition_arr
-       );
-   pfree(val);
-
-   PG_FREE_IF_COPY(query, 1);
-   PG_RETURN_BOOL(result);
-}
-
-static void
-findoprnd(ITEM * ptr, int4 *pos)
-{
-#ifdef BS_DEBUG
-   elog(DEBUG4, (ptr[*pos].type == OPR) ?
-        "%d  %c" : "%d  %d ", *pos, ptr[*pos].val);
-#endif
-   if (ptr[*pos].type == VAL)
-   {
-       ptr[*pos].left = 0;
-       (*pos)--;
-   }
-   else if (ptr[*pos].val == (int4) '!')
-   {
-       ptr[*pos].left = -1;
-       (*pos)--;
-       findoprnd(ptr, pos);
-   }
-   else
-   {
-       ITEM       *curitem = &ptr[*pos];
-       int4        tmp = *pos;
-
-       (*pos)--;
-       findoprnd(ptr, pos);
-       curitem->left = *pos - tmp;
-       findoprnd(ptr, pos);
-   }
-}
-
-
-/*
- * input
- */
-Datum
-bqarr_in(PG_FUNCTION_ARGS)
-{
-   char       *buf = (char *) PG_GETARG_POINTER(0);
-   WORKSTATE   state;
-   int4        i;
-   QUERYTYPE  *query;
-   int4        commonlen;
-   ITEM       *ptr;
-   NODE       *tmp;
-   int4        pos = 0;
-
-#ifdef BS_DEBUG
-   StringInfoData pbuf;
-#endif
-
-   state.buf = buf;
-   state.state = WAITOPERAND;
-   state.count = 0;
-   state.num = 0;
-   state.str = NULL;
-
-   /* make polish notation (postfix, but in reverse order) */
-   makepol(&state);
-   if (!state.num)
-       elog(ERROR, "Empty query");
-
-   commonlen = COMPUTESIZE(state.num);
-   query = (QUERYTYPE *) palloc(commonlen);
-   query->len = commonlen;
-   query->size = state.num;
-   ptr = GETQUERY(query);
-
-   for (i = state.num - 1; i >= 0; i--)
-   {
-       ptr[i].type = state.str->type;
-       ptr[i].val = state.str->val;
-       tmp = state.str->next;
-       pfree(state.str);
-       state.str = tmp;
-   }
-
-   pos = query->size - 1;
-   findoprnd(ptr, &pos);
-#ifdef BS_DEBUG
-   initStringInfo(&pbuf);
-   for (i = 0; i < query->size; i++)
-   {
-       if (ptr[i].type == OPR)
-           appendStringInfo(&pbuf, "%c(%d) ", ptr[i].val, ptr[i].left);
-       else
-           appendStringInfo(&pbuf, "%d ", ptr[i].val);
-   }
-   elog(DEBUG4, "POR: %s", pbuf.data);
-   pfree(pbuf.data);
-#endif
-
-   PG_RETURN_POINTER(query);
-}
-
-
-/*
- * out function
- */
-typedef struct
-{
-   ITEM       *curpol;
-   char       *buf;
-   char       *cur;
-   int4        buflen;
-}  INFIX;
-
-#define RESIZEBUF(inf,addsize) while( ( inf->cur - inf->buf ) + addsize + 1 >= inf->buflen ) { \
-   int4 len = inf->cur - inf->buf; \
-   inf->buflen *= 2; \
-   inf->buf = (char*) repalloc( (void*)inf->buf, inf->buflen ); \
-   inf->cur = inf->buf + len; \
-}
-
-static void
-infix(INFIX * in, bool first)
-{
-   if (in->curpol->type == VAL)
-   {
-       RESIZEBUF(in, 11);
-       sprintf(in->cur, "%d", in->curpol->val);
-       in->cur = strchr(in->cur, '\0');
-       in->curpol--;
-   }
-   else if (in->curpol->val == (int4) '!')
-   {
-       bool        isopr = false;
-
-       RESIZEBUF(in, 1);
-       *(in->cur) = '!';
-       in->cur++;
-       *(in->cur) = '\0';
-       in->curpol--;
-       if (in->curpol->type == OPR)
-       {
-           isopr = true;
-           RESIZEBUF(in, 2);
-           sprintf(in->cur, "( ");
-           in->cur = strchr(in->cur, '\0');
-       }
-       infix(in, isopr);
-       if (isopr)
-       {
-           RESIZEBUF(in, 2);
-           sprintf(in->cur, " )");
-           in->cur = strchr(in->cur, '\0');
-       }
-   }
-   else
-   {
-       int4        op = in->curpol->val;
-       INFIX       nrm;
-
-       in->curpol--;
-       if (op == (int4) '|' && !first)
-       {
-           RESIZEBUF(in, 2);
-           sprintf(in->cur, "( ");
-           in->cur = strchr(in->cur, '\0');
-       }
-
-       nrm.curpol = in->curpol;
-       nrm.buflen = 16;
-       nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
-
-       /* get right operand */
-       infix(&nrm, false);
-
-       /* get & print left operand */
-       in->curpol = nrm.curpol;
-       infix(in, false);
-
-       /* print operator & right operand */
-       RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
-       sprintf(in->cur, " %c %s", op, nrm.buf);
-       in->cur = strchr(in->cur, '\0');
-       pfree(nrm.buf);
-
-       if (op == (int4) '|' && !first)
-       {
-           RESIZEBUF(in, 2);
-           sprintf(in->cur, " )");
-           in->cur = strchr(in->cur, '\0');
-       }
-   }
-}
-
-
-Datum
-bqarr_out(PG_FUNCTION_ARGS)
-{
-   QUERYTYPE  *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
-   INFIX       nrm;
-
-   if (query->size == 0)
-       elog(ERROR, "Empty");
-   nrm.curpol = GETQUERY(query) + query->size - 1;
-   nrm.buflen = 32;
-   nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
-   *(nrm.cur) = '\0';
-   infix(&nrm, true);
-
-   PG_FREE_IF_COPY(query, 0);
-   PG_RETURN_POINTER(nrm.buf);
-}
-
-static int4
-countdroptree(ITEM * q, int4 pos)
-{
-   if (q[pos].type == VAL)
-       return 1;
-   else if (q[pos].val == (int4) '!')
-       return 1 + countdroptree(q, pos - 1);
-   else
-       return 1 + countdroptree(q, pos - 1) + countdroptree(q, pos + q[pos].left);
-}
-
-/*
- * common algorithm:
- * result of all '!' will be = 'true', so
- * we can modify query tree for clearing
- */
-static int4
-shorterquery(ITEM * q, int4 len)
-{
-   int4        index,
-               posnot,
-               poscor;
-   bool        notisleft = false;
-   int4        drop,
-               i;
-
-   /* out all '!' */
-   do
-   {
-       index = 0;
-       drop = 0;
-       /* find ! */
-       for (posnot = 0; posnot < len; posnot++)
-           if (q[posnot].type == OPR && q[posnot].val == (int4) '!')
-           {
-               index = 1;
-               break;
-           }
-
-       if (posnot == len)
-           return len;
-
-       /* last operator is ! */
-       if (posnot == len - 1)
-           return 0;
-
-       /* find operator for this operand */
-       for (poscor = posnot + 1; poscor < len; poscor++)
-       {
-           if (q[poscor].type == OPR)
-           {
-               if (poscor == posnot + 1)
-               {
-                   notisleft = false;
-                   break;
-               }
-               else if (q[poscor].left + poscor == posnot)
-               {
-                   notisleft = true;
-                   break;
-               }
-           }
-       }
-       if (q[poscor].val == (int4) '!')
-       {
-           drop = countdroptree(q, poscor);
-           q[poscor - 1].type = VAL;
-           for (i = poscor + 1; i < len; i++)
-               if (q[i].type == OPR && q[i].left + i <= poscor)
-                   q[i].left += drop - 2;
-           memcpy((void *) &q[poscor - drop + 1],
-                  (void *) &q[poscor - 1],
-                  sizeof(ITEM) * (len - (poscor - 1)));
-           len -= drop - 2;
-       }
-       else if (q[poscor].val == (int4) '|')
-       {
-           drop = countdroptree(q, poscor);
-           q[poscor - 1].type = VAL;
-           q[poscor].val = (int4) '!';
-           q[poscor].left = -1;
-           for (i = poscor + 1; i < len; i++)
-               if (q[i].type == OPR && q[i].left + i < poscor)
-                   q[i].left += drop - 2;
-           memcpy((void *) &q[poscor - drop + 1],
-                  (void *) &q[poscor - 1],
-                  sizeof(ITEM) * (len - (poscor - 1)));
-           len -= drop - 2;
-       }
-       else
-       {                       /* &-operator */
-           if (
-               (notisleft && q[poscor - 1].type == OPR &&
-                q[poscor - 1].val == (int4) '!') ||
-               (!notisleft && q[poscor + q[poscor].left].type == OPR &&
-                q[poscor + q[poscor].left].val == (int4) '!')
-               )
-           {                   /* drop subtree */
-               drop = countdroptree(q, poscor);
-               q[poscor - 1].type = VAL;
-               q[poscor].val = (int4) '!';
-               q[poscor].left = -1;
-               for (i = poscor + 1; i < len; i++)
-                   if (q[i].type == OPR && q[i].left + i < poscor)
-                       q[i].left += drop - 2;
-               memcpy((void *) &q[poscor - drop + 1],
-                      (void *) &q[poscor - 1],
-                      sizeof(ITEM) * (len - (poscor - 1)));
-               len -= drop - 2;
-           }
-           else
-           {                   /* drop only operator */
-               int4        subtreepos = (notisleft) ?
-               poscor - 1 : poscor + q[poscor].left;
-               int4        subtreelen = countdroptree(q, subtreepos);
-
-               drop = countdroptree(q, poscor);
-               for (i = poscor + 1; i < len; i++)
-                   if (q[i].type == OPR && q[i].left + i < poscor)
-                       q[i].left += drop - subtreelen;
-               memcpy((void *) &q[subtreepos + 1],
-                      (void *) &q[poscor + 1],
-                      sizeof(ITEM) * (len - (poscor - 1)));
-               memcpy((void *) &q[poscor - drop + 1],
-                      (void *) &q[subtreepos - subtreelen + 1],
-                      sizeof(ITEM) * (len - (drop - subtreelen)));
-               len -= drop - subtreelen;
-           }
-       }
-   } while (index);
-   return len;
-}
-
-
-Datum
-querytree(PG_FUNCTION_ARGS)
-{
-   QUERYTYPE  *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
-   INFIX       nrm;
-   text       *res;
-   ITEM       *q;
-   int4        len;
-
-   if (query->size == 0)
-       elog(ERROR, "Empty");
-
-   q = (ITEM *) palloc(sizeof(ITEM) * query->size);
-   memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size);
-   len = shorterquery(q, query->size);
-   PG_FREE_IF_COPY(query, 0);
-
-   if (len == 0)
-   {
-       res = (text *) palloc(1 + VARHDRSZ);
-       VARATT_SIZEP(res) = 1 + VARHDRSZ;
-       *((char *) VARDATA(res)) = 'T';
-   }
-   else
-   {
-       nrm.curpol = q + len - 1;
-       nrm.buflen = 32;
-       nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
-       *(nrm.cur) = '\0';
-       infix(&nrm, true);
-
-       res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ);
-       VARATT_SIZEP(res) = nrm.cur - nrm.buf + VARHDRSZ;
-       strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf);
-   }
-   pfree(q);
-
-   PG_RETURN_POINTER(res);
-}
-
-/*
-** Additional array functions
-*/
-static int32 intarray_match_first(ArrayType *a, int32 elem);
-static ArrayType *intarray_add_elem(ArrayType *a, int32 elem);
-static ArrayType *intarray_concat_arrays(ArrayType *a, ArrayType *b);
-static ArrayType *int_to_intset(int32 elem);
-
-PG_FUNCTION_INFO_V1(intset);
-PG_FUNCTION_INFO_V1(icount);
-PG_FUNCTION_INFO_V1(sort);
-PG_FUNCTION_INFO_V1(sort_asc);
-PG_FUNCTION_INFO_V1(sort_desc);
-PG_FUNCTION_INFO_V1(uniq);
-PG_FUNCTION_INFO_V1(idx);
-PG_FUNCTION_INFO_V1(subarray);
-PG_FUNCTION_INFO_V1(intarray_push_elem);
-PG_FUNCTION_INFO_V1(intarray_push_array);
-PG_FUNCTION_INFO_V1(intarray_del_elem);
-PG_FUNCTION_INFO_V1(intset_union_elem);
-PG_FUNCTION_INFO_V1(intset_subtract);
-Datum      intset(PG_FUNCTION_ARGS);
-Datum      icount(PG_FUNCTION_ARGS);
-Datum      sort(PG_FUNCTION_ARGS);
-Datum      sort_asc(PG_FUNCTION_ARGS);
-Datum      sort_desc(PG_FUNCTION_ARGS);
-Datum      uniq(PG_FUNCTION_ARGS);
-Datum      idx(PG_FUNCTION_ARGS);
-Datum      subarray(PG_FUNCTION_ARGS);
-Datum      intarray_push_elem(PG_FUNCTION_ARGS);
-Datum      intarray_push_array(PG_FUNCTION_ARGS);
-Datum      intarray_del_elem(PG_FUNCTION_ARGS);
-Datum      intset_union_elem(PG_FUNCTION_ARGS);
-Datum      intset_subtract(PG_FUNCTION_ARGS);
-
-static int32
-intarray_match_first(ArrayType *a, int32 elem)
-{
-   int32      *aa,
-               c,
-               i;
-
-   c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-   aa = ARRPTR(a);
-   for (i = 0; i < c; i++)
-       if (aa[i] == elem)
-           return (i + 1);
-   return 0;
-}
-
-static ArrayType *
-intarray_add_elem(ArrayType *a, int32 elem)
-{
-   ArrayType  *result;
-   int32      *r;
-   int32       c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-
-   result = new_intArrayType(c + 1);
-   r = ARRPTR(result);
-   if (c > 0)
-       memcpy(r, ARRPTR(a), c * sizeof(int32));
-   r[c] = elem;
-   return result;
-}
-
-static ArrayType *
-intarray_concat_arrays(ArrayType *a, ArrayType *b)
-{
-   ArrayType  *result;
-   int32       ac = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-   int32       bc = (ARRISVOID(b)) ? 0 : ARRNELEMS(b);
-
-   result = new_intArrayType(ac + bc);
-   if (ac)
-       memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
-   if (bc)
-       memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
-   return result;
-}
-
-static ArrayType *
-int_to_intset(int32 n)
-{
-   ArrayType  *result;
-   int32      *aa;
-
-   result = new_intArrayType(1);
-   aa = ARRPTR(result);
-   aa[0] = n;
-   return result;
-}
-
-static int
-compASC(const void *a, const void *b)
-{
-   if (*(int4 *) a == *(int4 *) b)
-       return 0;
-   return (*(int4 *) a > *(int4 *) b) ? 1 : -1;
-}
-
-static int
-compDESC(const void *a, const void *b)
-{
-   if (*(int4 *) a == *(int4 *) b)
-       return 0;
-   return (*(int4 *) a < *(int4 *) b) ? 1 : -1;
-}
-
-#define QSORT(a, direction)                        \
-if (ARRNELEMS(a) > 1)                      \
-   qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4),  \
-       (direction) ? compASC : compDESC )
-
-
-Datum
-intset(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
-}
-
-Datum
-icount(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   int32       count = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-
-   PG_FREE_IF_COPY(a, 0);
-   PG_RETURN_INT32(count);
-}
-
-Datum
-sort(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   text       *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_P(1) : NULL;
-   int32       dc = (dirstr) ? VARSIZE(dirstr) - VARHDRSZ : 0;
-   char       *d = (dirstr) ? VARDATA(dirstr) : NULL;
-   int         dir = -1;
-
-   if (ARRISVOID(a) || ARRNELEMS(a) < 2)
-       PG_RETURN_POINTER(a);
-
-   if (dirstr == NULL || (dc == 3
-                          && (d[0] == 'A' || d[0] == 'a')
-                          && (d[1] == 'S' || d[1] == 's')
-                          && (d[2] == 'C' || d[2] == 'c')))
-       dir = 1;
-   else if (dc == 4
-            && (d[0] == 'D' || d[0] == 'd')
-            && (d[1] == 'E' || d[1] == 'e')
-            && (d[2] == 'S' || d[2] == 's')
-            && (d[3] == 'C' || d[3] == 'c'))
-       dir = 0;
-   if (dir == -1)
-       elog(ERROR, "Invalid second parameter in function sort. It must be 'ASC' or 'DESC'.");
-   QSORT(a, dir);
-   PG_RETURN_POINTER(a);
-}
-
-Datum
-sort_asc(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-
-   if (ARRISVOID(a))
-       PG_RETURN_POINTER(a);
-   QSORT(a, 1);
-   PG_RETURN_POINTER(a);
-}
-
-Datum
-sort_desc(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-
-   if (ARRISVOID(a))
-       PG_RETURN_POINTER(a);
-   QSORT(a, 0);
-   PG_RETURN_POINTER(a);
-}
-
-Datum
-uniq(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-
-   if (ARRISVOID(a) || ARRNELEMS(a) < 2)
-       PG_RETURN_POINTER(a);
-   UNIX_UNIQ(a);
-   PG_RETURN_POINTER(a);
-}
-
-Datum
-idx(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   int32       result = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-
-   if (result)
-       result = intarray_match_first(a, PG_GETARG_INT32(1));
-   PG_FREE_IF_COPY(a, 0);
-   PG_RETURN_INT32(result);
-}
-
-Datum
-subarray(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   ArrayType  *result;
-   int32       start = (PG_GETARG_INT32(1) > 0) ? PG_GETARG_INT32(1) - 1 : PG_GETARG_INT32(1);
-   int32       len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
-   int32       end = 0;
-   int32       c;
-
-   if (ARRISVOID(a))
-   {
-       PG_FREE_IF_COPY(a, 0);
-       PG_RETURN_POINTER(new_intArrayType(0));
-   }
-
-   c = ARRNELEMS(a);
-
-   if (start < 0)
-       start = c + start;
-
-   if (len < 0)
-       end = c + len;
-   else if (len == 0)
-       end = c;
-   else
-       end = start + len;
-
-   if (end > c)
-       end = c;
-
-   if (start < 0)
-       start = 0;
-
-   if (start >= end || end <= 0)
-   {
-       PG_FREE_IF_COPY(a, 0);
-       PG_RETURN_POINTER(new_intArrayType(0));
-   }
-
-
-   result = new_intArrayType(end - start);
-   if (end - start > 0)
-       memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
-   PG_FREE_IF_COPY(a, 0);
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-intarray_push_elem(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   ArrayType  *result;
-
-   result = intarray_add_elem(a, PG_GETARG_INT32(1));
-   PG_FREE_IF_COPY(a, 0);
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-intarray_push_array(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
-   ArrayType  *result;
-
-   result = intarray_concat_arrays(a, b);
-   PG_FREE_IF_COPY(a, 0);
-   PG_FREE_IF_COPY(b, 1);
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-intarray_del_elem(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   int32       c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-   int32      *aa = ARRPTR(a);
-   int32       n = 0,
-               i;
-   int32       elem = PG_GETARG_INT32(1);
-
-   for (i = 0; i < c; i++)
-       if (aa[i] != elem)
-       {
-           if (i > n)
-               aa[n++] = aa[i];
-           else
-               n++;
-       }
-   if (c > 0)
-       a = resize_intArrayType(a, n);
-   PG_RETURN_POINTER(a);
-}
-
-Datum
-intset_union_elem(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-   ArrayType  *result;
-
-   result = intarray_add_elem(a, PG_GETARG_INT32(1));
-   PG_FREE_IF_COPY(a, 0);
-   QSORT(result, 1);
-   UNIX_UNIQ(result);
-   PG_RETURN_POINTER(result);
-}
-
-Datum
-intset_subtract(PG_FUNCTION_ARGS)
-{
-   ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-   ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
-   ArrayType  *result;
-   int32       ca = ARRISVOID(a);
-   int32       cb = ARRISVOID(b);
-   int32      *aa,
-              *bb,
-              *r;
-   int32       n = 0,
-               i = 0,
-               k = 0;
-
-   QSORT(a, 1);
-   UNIX_UNIQ(a);
-   ca = ARRNELEMS(a);
-   QSORT(b, 1);
-   UNIX_UNIQ(b);
-   cb = ARRNELEMS(b);
-   result = new_intArrayType(ca);
-   aa = ARRPTR(a);
-   bb = ARRPTR(b);
-   r = ARRPTR(result);
-   while (i < ca)
-   {
-       if (k == cb || aa[i] < bb[k])
-           r[n++] = aa[i++];
-       else if (aa[i] == bb[k])
-       {
-           i++;
-           k++;
-       }
-       else
-           k++;
-   }
-   result = resize_intArrayType(result, n);
-   pfree(a);
-   pfree(b);
-   PG_RETURN_POINTER(result);
-}
index 21786e51e7ad150c287e37f2118b55d573db26b7..2c30bac99e5c6e02e284c34729c8ce3ce5d8ff0e 100644 (file)
@@ -360,7 +360,24 @@ DEFAULT FOR TYPE _int4 USING gist AS
 -- intbig
 ---------------------------------------------
 -- define the GiST support methods
-CREATE FUNCTION g_intbig_consistent(internal,_int4,int4)
+
+CREATE FUNCTION _intbig_in(cstring)
+RETURNS intbig_gkey
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C' with (isstrict);
+
+CREATE FUNCTION _intbig_out(intbig_gkey)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C' with (isstrict);
+
+CREATE TYPE intbig_gkey (
+        INTERNALLENGTH = -1,
+        INPUT = _intbig_in,
+        OUTPUT = _intbig_out
+);
+
+CREATE FUNCTION g_intbig_consistent(internal,internal,int4)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C';
@@ -390,7 +407,7 @@ RETURNS _int4
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C';
 
-CREATE FUNCTION g_intbig_same(_int4, _int4, internal)
+CREATE FUNCTION g_intbig_same(internal, internal, internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C';
@@ -405,10 +422,11 @@ AS
    OPERATOR    7   @   RECHECK,
    OPERATOR    8   ~   RECHECK,
    OPERATOR    20  @@ (_int4, query_int)   RECHECK,
-   FUNCTION    1   g_intbig_consistent (internal, _int4, int4),
+   FUNCTION    1   g_intbig_consistent (internal, internal, int4),
    FUNCTION    2   g_intbig_union (bytea, internal),
    FUNCTION    3   g_intbig_compress (internal),
    FUNCTION    4   g_intbig_decompress (internal),
    FUNCTION    5   g_intbig_penalty (internal, internal, internal),
    FUNCTION    6   g_intbig_picksplit (internal, internal),
-   FUNCTION    7   g_intbig_same (_int4, _int4, internal);
+   FUNCTION    7   g_intbig_same (internal, internal, internal),
+   STORAGE     intbig_gkey;
index b602df33d838002d98c46364b88dc4524222f079..142697f22564671dbb48cf35c7007a121762aac3 100644 (file)
@@ -5,6 +5,8 @@
 \set ECHO none
 psql:_int.sql:13: NOTICE:  ProcedureCreate: type query_int is not yet defined
 psql:_int.sql:18: NOTICE:  Argument type "query_int" is only a shell
+psql:_int.sql:369: NOTICE:  ProcedureCreate: type intbig_gkey is not yet defined
+psql:_int.sql:374: NOTICE:  Argument type "intbig_gkey" is only a shell
 SELECT intset(1234);
  intset 
 --------
index 1791f5bd8d47a43dc456789ecb160518eed27956..ec20067230e84c7ec326bba3e0dfe1efbf563dac 100644 (file)
@@ -211,35 +211,39 @@ sizebitvec(BITVECP sign)
    return size;
 }
 
+static int                      
+hemdistsign(BITVECP  a, BITVECP b) {
+   int i,dist=0;
+                 
+   ALOOPBIT(
+       if ( GETBIT(a,i) != GETBIT(b,i) )
+           dist++;
+   );
+   return dist;
+}
+
+static int
+hemdist(ltree_gist   *a, ltree_gist   *b) {
+        if ( LTG_ISALLTRUE(a) ) {   
+                if (LTG_ISALLTRUE(b))
+                        return 0;
+                else
+                        return ASIGLENBIT-sizebitvec(LTG_SIGN(b));
+        } else if (LTG_ISALLTRUE(b))
+                return ASIGLENBIT-sizebitvec(LTG_SIGN(a));
+        return hemdistsign( LTG_SIGN(a), LTG_SIGN(b) );
+}
+
+
 Datum
 _ltree_penalty(PG_FUNCTION_ARGS)
 {
    ltree_gist *origval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
    ltree_gist *newval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
    float      *penalty = (float *) PG_GETARG_POINTER(2);
-   BITVECP     orig = LTG_SIGN(origval);
 
-   if (LTG_ISALLTRUE(origval))
-   {
-       *penalty = 0.1;
-       PG_RETURN_POINTER(penalty);
-   }
-
-   if (LTG_ISALLTRUE(newval))
-       *penalty = (float) (ASIGLENBIT - sizebitvec(orig));
-   else
-   {
-       unsigned char valtmp;
-       BITVECP     nval = LTG_SIGN(newval);
-       int4        i,
-                   unionsize = 0;
-
-       ALOOPBYTE(
-                 valtmp = nval[i] | orig[i];
-       unionsize += SUMBIT(valtmp) - SUMBIT(orig[i]);
-       );
-       *penalty = (float) unionsize;
-   }
+   *penalty=hemdist(origval,newval);
    PG_RETURN_POINTER(penalty);
 }
 
@@ -264,28 +268,19 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
                j;
    ltree_gist *datum_l,
               *datum_r;
-   ABITVEC     union_l,
+   BITVECP     union_l,
                union_r;
-   bool        firsttime = true;
-   int4        size_alpha,
-               size_beta,
-               sizeu,
-               sizei;
+   int4        size_alpha, size_beta;
    int4        size_waste,
-               waste = 0.0;
-   int4        size_l,
-               size_r;
+               waste = -1;
    int4        nbytes;
    OffsetNumber seed_1 = 0,
                seed_2 = 0;
    OffsetNumber *left,
               *right;
    OffsetNumber maxoff;
-   BITVECP     ptra,
-               ptrb,
-               ptrc;
+   BITVECP     ptr;
    int         i;
-   unsigned char valtmp;
    SPLITCOST  *costvector;
    ltree_gist *_k,
               *_j;
@@ -295,57 +290,14 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
    v->spl_left = (OffsetNumber *) palloc(nbytes);
    v->spl_right = (OffsetNumber *) palloc(nbytes);
 
-   for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
-   {
+   for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) {
        _k = GETENTRY(entryvec, k);
-       for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
-       {
-           _j = GETENTRY(entryvec, j);
-           if (LTG_ISALLTRUE(_k) || LTG_ISALLTRUE(_j))
-           {
-               sizeu = ASIGLENBIT;
-               if (LTG_ISALLTRUE(_k) && LTG_ISALLTRUE(_j))
-                   sizei = ASIGLENBIT;
-               else
-                   sizei = (LTG_ISALLTRUE(_k)) ?
-                       sizebitvec(LTG_SIGN(_j)) : sizebitvec(LTG_SIGN(_k));
-           }
-           else
-           {
-               sizeu = sizei = 0;
-               ptra = LTG_SIGN(_j);
-               ptrb = LTG_SIGN(_k);
-               /* critical section for bench !!! */
-
-#define COUNT(pos) do { \
-   if ( GETBITBYTE(*(char*)ptra,pos) ) { \
-       sizeu++; \
-       if ( GETBITBYTE(*(char*)ptrb, pos) ) \
-           sizei++; \
-   } else if ( GETBITBYTE(*(char*)ptrb, pos) ) \
-       sizeu++; \
-} while(0)
-
-               ALOOPBYTE(
-                         COUNT(0);
-               COUNT(1);
-               COUNT(2);
-               COUNT(3);
-               COUNT(4);
-               COUNT(5);
-               COUNT(6);
-               COUNT(7);
-               ptra = (BITVECP) (((char *) ptra) + 1);
-               ptrb = (BITVECP) (((char *) ptrb) + 1);
-               );
-           }
-           size_waste = sizeu - sizei;
-           if (size_waste > waste || firsttime)
-           {
+       for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) {
+           size_waste=hemdist(_k, GETENTRY(entryvec, j));
+           if (size_waste > waste ) {
                waste = size_waste;
                seed_1 = k;
                seed_2 = j;
-               firsttime = false;
            }
        }
    }
@@ -367,7 +319,6 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
        datum_l = (ltree_gist *) palloc(LTG_HDRSIZE);
        datum_l->len = LTG_HDRSIZE;
        datum_l->flag = LTG_ALLTRUE;
-       size_l = ASIGLENBIT;
    }
    else
    {
@@ -375,14 +326,12 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
        datum_l->len = LTG_HDRSIZE + ASIGLEN;
        datum_l->flag = 0;
        memcpy((void *) LTG_SIGN(datum_l), (void *) LTG_SIGN(GETENTRY(entryvec, seed_1)), sizeof(ABITVEC));
-       size_l = sizebitvec(LTG_SIGN(datum_l));
    }
    if (LTG_ISALLTRUE(GETENTRY(entryvec, seed_2)))
    {
        datum_r = (ltree_gist *) palloc(LTG_HDRSIZE);
        datum_r->len = LTG_HDRSIZE;
        datum_r->flag = LTG_ALLTRUE;
-       size_r = ASIGLENBIT;
    }
    else
    {
@@ -390,7 +339,6 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
        datum_r->len = LTG_HDRSIZE + ASIGLEN;
        datum_r->flag = 0;
        memcpy((void *) LTG_SIGN(datum_r), (void *) LTG_SIGN(GETENTRY(entryvec, seed_2)), sizeof(ABITVEC));
-       size_r = sizebitvec(LTG_SIGN(datum_r));
    }
 
    maxoff = OffsetNumberNext(maxoff);
@@ -400,55 +348,18 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
    {
        costvector[j - 1].pos = j;
        _j = GETENTRY(entryvec, j);
-       if (LTG_ISALLTRUE(_j))
-       {
-           size_alpha = ASIGLENBIT - size_l;
-           size_beta = ASIGLENBIT - size_r;
-       }
-       else
-       {
-           ptra = LTG_SIGN(datum_l);
-           ptrb = LTG_SIGN(datum_r);
-           ptrc = LTG_SIGN(_j);
-           size_beta = size_alpha = 0;
-           if (LTG_ISALLTRUE(datum_l))
-           {
-               if (!LTG_ISALLTRUE(datum_r))
-               {
-                   ALOOPBIT(
-                            if (GETBIT(ptrc, i) && !GETBIT(ptrb, i))
-                            size_beta++;
-                   );
-               }
-           }
-           else if (LTG_ISALLTRUE(datum_r))
-           {
-               if (!LTG_ISALLTRUE(datum_l))
-               {
-                   ALOOPBIT(
-                            if (GETBIT(ptrc, i) && !GETBIT(ptra, i))
-                            size_alpha++;
-                   );
-               }
-           }
-           else
-           {
-               ALOOPBIT(
-                        if (GETBIT(ptrc, i) && !GETBIT(ptra, i))
-                        size_alpha++;
-               if (GETBIT(ptrc, i) && !GETBIT(ptrb, i))
-                   size_beta++;
-               );
-           }
-       }
+       size_alpha = hemdist(datum_l,_j);
+       size_beta  = hemdist(datum_r,_j);
        costvector[j - 1].cost = abs(size_alpha - size_beta);
    }
    qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
 
+   union_l=LTG_SIGN(datum_l);
+   union_r=LTG_SIGN(datum_r);
+   
    for (k = 0; k < maxoff; k++)
    {
        j = costvector[k].pos;
-       _j = GETENTRY(entryvec, j);
        if (j == seed_1)
        {
            *left++ = j;
@@ -461,62 +372,35 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
            v->spl_nright++;
            continue;
        }
+       _j = GETENTRY(entryvec, j);
+       size_alpha = hemdist(datum_l,_j);
+       size_beta  = hemdist(datum_r,_j);
 
-       if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j))
-           size_alpha = ASIGLENBIT;
-       else
-       {
-           ptra = LTG_SIGN(_j);
-           ptrb = LTG_SIGN(datum_l);
-           size_alpha = 0;
-           ALOOPBYTE(
-                     valtmp = union_l[i] = ptra[i] | ptrb[i];
-           size_alpha += SUMBIT(valtmp);
-           );
-       }
-
-       if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j))
-           size_beta = ASIGLENBIT;
-       else
-       {
-           ptra = LTG_SIGN(_j);
-           ptrb = LTG_SIGN(datum_r);
-           size_beta = 0;
-           ALOOPBYTE(
-                     valtmp = union_r[i] = ptra[i] | ptrb[i];
-           size_beta += SUMBIT(valtmp);
-           );
-       }
-
-       if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
+       if (size_alpha < size_beta  + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
        {
-           if (!LTG_ISALLTRUE(datum_l))
-           {
-               if (size_alpha == ASIGLENBIT)
-               {
-                   if (size_alpha != size_l)
-                       MemSet((void *) LTG_SIGN(datum_l), 0xff, sizeof(ABITVEC));
-               }
-               else
-                   memcpy((void *) LTG_SIGN(datum_l), (void *) union_l, sizeof(ABITVEC));
+           if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j) ) {
+               if (!LTG_ISALLTRUE(datum_l))
+                   MemSet((void *) union_l, 0xff, sizeof(ABITVEC)); 
+           } else {
+               ptr=LTG_SIGN(_j);
+               ALOOPBYTE(
+                   union_l[i] |= ptr[i];
+               );
            }
-           size_l = size_alpha;
            *left++ = j;
            v->spl_nleft++;
        }
        else
        {
-           if (!LTG_ISALLTRUE(datum_r))
-           {
-               if (size_beta == ASIGLENBIT)
-               {
-                   if (size_beta != size_r)
-                       MemSet((void *) LTG_SIGN(datum_r), 0xff, sizeof(ABITVEC));
-               }
-               else
-                   memcpy((void *) LTG_SIGN(datum_r), (void *) union_r, sizeof(ABITVEC));
+           if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j) ) {
+               if (!LTG_ISALLTRUE(datum_r))
+                   MemSet((void *) union_r, 0xff, sizeof(ABITVEC)); 
+           } else {
+               ptr=LTG_SIGN(_j);
+               ALOOPBYTE(
+                   union_r[i] |= ptr[i];
+               );
            }
-           size_r = size_beta;
            *right++ = j;
            v->spl_nright++;
        }
index 1bc36e722de3534afb868c06387eeced8ef0fb1d..39bc0cd311daae0d3d63930bc29e32cf9db21fe3 100644 (file)
@@ -239,7 +239,7 @@ typedef struct
 
 /* GiST support for ltree[] */
 
-#define ASIGLENINT (2*SIGLENINT)
+#define ASIGLENINT (7)
 #define ASIGLEN        (sizeof(int4)*ASIGLENINT)
 #define ASIGLENBIT (ASIGLEN*BITBYTE)
 typedef unsigned char ABITVEC[ASIGLEN];