aboutsummaryrefslogtreecommitdiff
path: root/contrib/intarray/_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/intarray/_int.c')
-rw-r--r--contrib/intarray/_int.c384
1 files changed, 201 insertions, 183 deletions
diff --git a/contrib/intarray/_int.c b/contrib/intarray/_int.c
index 3d615ef2c40..352f5ce48f8 100644
--- a/contrib/intarray/_int.c
+++ b/contrib/intarray/_int.c
@@ -4,6 +4,11 @@
format for these routines is dictated by Postgres architecture.
******************************************************************************/
+/*
+#define GIST_DEBUG
+#define GIST_QUERY_DEBUG
+*/
+
#include "postgres.h"
#include <float.h>
@@ -17,32 +22,46 @@
#include "utils/builtins.h"
#include "storage/bufpage.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
+
+/* useful macros for accessing int4 arrays */
#define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
#ifdef PGSQL71
-#define ARRSIZE(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
+#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
#else
-#define ARRSIZE(x) getNitems( ARR_NDIM(x), ARR_DIMS(x))
+#define ARRNELEMS(x) getNitems( ARR_NDIM(x), ARR_DIMS(x))
#endif
-#define NDIM 1
+#define ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : 1 ) : 1 )
+
+#define SORT(x) \
+ do { \
+ if ( ARRNELEMS( x ) > 1 ) \
+ isort( (void*)ARRPTR( x ), ARRNELEMS( x ) ); \
+ } while(0)
-#define ARRISNULL(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRSIZE( x ) ) ? 0 : 1 ) : 1 ) : 1 )
-#define SORT(x) if ( ARRSIZE( x ) > 1 ) isort( (void*)ARRPTR( x ), ARRSIZE( x ) );
#define PREPAREARR(x) \
- if ( ARRSIZE( x ) > 1 ) {\
- if ( isort( (void*)ARRPTR( x ), ARRSIZE( x ) ) )\
- x = _int_unique( x );\
- }
+ do { \
+ if ( ARRNELEMS( x ) > 1 ) \
+ if ( isort( (void*)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 128
+#define SIGLENINT 64 /* >122 => key will toast, so very slow!!! */
#define SIGLEN ( sizeof(int)*SIGLENINT )
#define SIGLENBIT (SIGLEN*BITBYTE)
@@ -50,10 +69,6 @@ typedef char BITVEC[SIGLEN];
typedef char* BITVECP;
#define SIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) )
-#define NULLIFY(a) MemSet( a, 0, sizeof( BITVEC ) )
-#define NEWSIG(a) \
- a=(BITVECP) malloc( sizeof( BITVEC ) );\
- NULLIFY(a);
#define LOOPBYTE(a) \
for(i=0;i<SIGLEN;i++) {\
@@ -71,13 +86,7 @@ typedef char* BITVECP;
#define SETBIT(x,i) GETBYTEBIT(x,i) |= ( 0x01 << ( (i) % BITBYTE ) )
#define GETBIT(x,i) ( (GETBYTEBIT(x,i) >> ( (i) % BITBYTE )) & 0x01 )
-#define union_sig(a,b,r) LOOPBYTE(r[i] = a[i] | b[i])
-#define inter_sig(a,b,r) LOOPBYTE(r[i] = a[i] & b[i])
-/*
-#define GIST_DEBUG
-#define GIST_QUERY_DEBUG
-*/
#ifdef GIST_DEBUG
static void printarr ( ArrayType * a, int num ) {
char bbb[16384];
@@ -87,7 +96,7 @@ static void printarr ( ArrayType * a, int num ) {
d = ARRPTR( a );
*bbb = '\0';
cur = bbb;
- for(l=0; l<min( num, ARRSIZE( a ));l++) {
+ for(l=0; l<min( num, ARRNELEMS( a ));l++) {
sprintf(cur,"%d ", d[l] );
cur = strchr( cur, '\0' ) ;
}
@@ -119,12 +128,13 @@ 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*/
+/* common GiST function*/
static GIST_SPLITVEC * _int_common_picksplit(bytea *entryvec,
GIST_SPLITVEC *v,
formarray unionf,
formarray interf,
- formfloat sizef);
+ formfloat sizef,
+ float coef);
static float * _int_common_penalty(GISTENTRY *origentry,
GISTENTRY *newentry,
float *result,
@@ -147,7 +157,7 @@ bool * g_int_same(ArrayType *b1, ArrayType *b2, bool *result);
/*
-** R-tree suport functions
+** R-tree support functions
*/
bool inner_int_contains(ArrayType *a, ArrayType *b);
bool inner_int_overlap(ArrayType *a, ArrayType *b);
@@ -199,6 +209,8 @@ g_int_consistent(GISTENTRY *entry,
bool retval;
/* sort query for fast search, key is already sorted */
+ /* XXX are we sure it's safe to scribble on the query object here? */
+ /* XXX what about toasted input? */
if ( ARRISNULL( query ) ) return FALSE;
PREPAREARR( query );
@@ -238,21 +250,29 @@ g_int_compress(GISTENTRY *entry)
int i,min,cand;
retval = palloc(sizeof(GISTENTRY));
- if ( ! retval )
- elog(ERROR,"Can't allocate memory for compression");
- if ( ARRISNULL( (ArrayType *) entry->pred ) ) {
+#ifdef PGSQL71
+ if ( entry->pred )
+ r = (ArrayType *)PG_DETOAST_DATUM_COPY( entry->pred );
+ else
+ r = NULL;
+#else
+ r = copy_intArrayType( (ArrayType *) entry->pred );
+#endif
+
+ if ( ARRISNULL( r ) ) {
#ifdef GIST_DEBUG
elog(NOTICE,"COMP IN: NULL");
#endif
- gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset,
- 0, FALSE);
+ if ( r ) if ( (char*)r != (char*)entry->pred ) pfree(r);
+
+ gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset,
+ 0, FALSE);
return( retval );
}
-
- r = copy_intArrayType( (ArrayType *) entry->pred );
+
if ( entry->leafkey ) PREPAREARR( r );
- len = ARRSIZE( r );
+ len = ARRNELEMS( r );
#ifdef GIST_DEBUG
elog(NOTICE, "COMP IN: %d leaf; %d rel; %d page; %d offset; %d bytes; %d elems", entry->leafkey, (int)entry->rel, (int)entry->page, (int)entry->offset, (int)entry->bytes, len);
@@ -297,10 +317,21 @@ g_int_decompress(GISTENTRY *entry)
int *din;
int i,j;
- if ( entry->bytes < ARR_OVERHEAD( NDIM ) || ARRISNULL( (ArrayType *) entry->pred ) ) {
+#ifdef PGSQL71
+ if ( entry->pred )
+ in = (ArrayType *)PG_DETOAST_DATUM( entry->pred );
+ else
+ in = NULL;
+#else
+ in = (ArrayType *) entry->pred;
+#endif
+
+ if ( entry->bytes < ARR_OVERHEAD( NDIM ) || ARRISNULL( in ) ) {
retval = palloc(sizeof(GISTENTRY));
- if ( ! retval )
- elog(ERROR,"Can't allocate memory for decompression");
+
+#ifdef PGSQL71
+ if ( in ) if ( (char*)in != (char*)entry->pred ) pfree(in);
+#endif
gistentryinit(*retval, (char *)NULL, entry->rel, entry->page, entry->offset, 0, FALSE);
#ifdef GIST_DEBUG
elog(NOTICE,"DECOMP IN: NULL");
@@ -309,8 +340,7 @@ g_int_decompress(GISTENTRY *entry)
}
- in = (ArrayType *) entry->pred;
- lenin = ARRSIZE(in);
+ lenin = ARRNELEMS(in);
din = ARRPTR(in);
if ( lenin < 2*MAXNUMRANGE ) { /*not comressed value*/
@@ -333,9 +363,11 @@ g_int_decompress(GISTENTRY *entry)
if ( (!i) || *(dr-1) != j )
*dr++ = j;
+#ifdef PGSQL71
+ if ( (char*)in != (char*)entry->pred ) pfree(in);
+#endif
retval = palloc(sizeof(GISTENTRY));
- if ( ! retval )
- elog(ERROR,"Can't allocate memory for decompression");
+
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
return(retval);
@@ -355,11 +387,11 @@ GIST_SPLITVEC *
g_int_picksplit(bytea *entryvec,
GIST_SPLITVEC *v)
{
-
return _int_common_picksplit( entryvec, v,
inner_int_union,
inner_int_inter,
- rt__int_size);
+ rt__int_size,
+ 1e-8);
}
/*
@@ -387,6 +419,7 @@ bool
_int_contains ( ArrayType *a, ArrayType *b ) {
bool res;
ArrayType *an, *bn;
+
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
an = copy_intArrayType( a );
@@ -408,8 +441,8 @@ inner_int_contains ( ArrayType *a, ArrayType *b ) {
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
- na = ARRSIZE( a );
- nb = ARRSIZE( b );
+ na = ARRNELEMS( a );
+ nb = ARRNELEMS( b );
da = ARRPTR( a );
db = ARRPTR( b );
@@ -444,39 +477,62 @@ _int_same ( ArrayType *a, ArrayType *b ) {
int na , nb ;
int n;
int *da, *db;
+ bool result;
+ ArrayType *an, *bn;
bool anull = ARRISNULL( a );
bool bnull = ARRISNULL( b );
if ( anull || bnull )
return ( anull && bnull ) ? TRUE : FALSE;
-
- SORT( a );
- SORT( b );
- na = ARRSIZE( a );
- nb = ARRSIZE( b );
- da = ARRPTR( a );
- db = ARRPTR( b );
- if ( na != nb ) return FALSE;
-
- n = 0;
+ an = copy_intArrayType( a );
+ bn = copy_intArrayType( b );
+
+ SORT( an );
+ SORT( bn );
+ na = ARRNELEMS( an );
+ nb = ARRNELEMS( bn );
+ da = ARRPTR( an );
+ db = ARRPTR( bn );
+
+ result = FALSE;
+
+ if ( na == nb )
+ {
+ result = TRUE;
for(n=0; n<na; n++)
if ( da[n] != db[n] )
- return FALSE;
+ {
+ result = FALSE;
+ break;
+ }
+ }
+
+ pfree( an ); pfree( bn );
- return TRUE;
+ return result;
}
/* _int_overlap -- does a overlap b?
*/
bool
_int_overlap ( ArrayType *a, ArrayType *b ) {
+ bool result;
+ ArrayType *an, *bn;
+
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
- SORT(a);
- SORT(b);
+ an = copy_intArrayType( a );
+ bn = copy_intArrayType( b );
- return inner_int_overlap( a, b );
+ SORT(an);
+ SORT(bn);
+
+ result = inner_int_overlap( an, bn );
+
+ pfree( an ); pfree( bn );
+
+ return result;
}
bool
@@ -487,8 +543,8 @@ inner_int_overlap ( ArrayType *a, ArrayType *b ) {
if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
- na = ARRSIZE( a );
- nb = ARRSIZE( b );
+ na = ARRNELEMS( a );
+ nb = ARRNELEMS( b );
da = ARRPTR( a );
db = ARRPTR( b );
@@ -510,10 +566,21 @@ inner_int_overlap ( ArrayType *a, ArrayType *b ) {
ArrayType *
_int_union ( ArrayType *a, ArrayType *b ) {
- if ( ! ARRISNULL( a ) ) SORT(a);
- if ( ! ARRISNULL( b ) ) SORT(b);
+ ArrayType *result;
+ ArrayType *an, *bn;
+
+ an = copy_intArrayType( a );
+ bn = copy_intArrayType( b );
+
+ if ( ! ARRISNULL( an ) ) SORT(an);
+ if ( ! ARRISNULL( bn ) ) SORT(bn);
- return inner_int_union( a, b );
+ result = inner_int_union( an, bn );
+
+ if (an) pfree( an );
+ if (bn) pfree( bn );
+
+ return result;
}
ArrayType *
@@ -534,8 +601,8 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
if ( r ) {
dr = ARRPTR( r );
} else {
- na = ARRSIZE( a );
- nb = ARRSIZE( b );
+ na = ARRNELEMS( a );
+ nb = ARRNELEMS( b );
da = ARRPTR( a );
db = ARRPTR( b );
@@ -555,7 +622,7 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
}
- if ( ARRSIZE(r) > 1 )
+ if ( ARRNELEMS(r) > 1 )
r = _int_unique( r );
return r;
@@ -564,12 +631,22 @@ inner_int_union ( ArrayType *a, ArrayType *b ) {
ArrayType *
_int_inter ( ArrayType *a, ArrayType *b ) {
- if ( ARRISNULL( a ) || ARRISNULL( b ) ) return FALSE;
+ ArrayType *result;
+ ArrayType *an, *bn;
- SORT(a);
- SORT(b);
+ if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
+
+ an = copy_intArrayType( a );
+ bn = copy_intArrayType( b );
+
+ SORT(an);
+ SORT(bn);
- return inner_int_inter( a, b );
+ result = inner_int_inter( an, bn );
+
+ pfree( an ); pfree( bn );
+
+ return result;
}
ArrayType *
@@ -583,10 +660,10 @@ inner_int_inter ( ArrayType *a, ArrayType *b ) {
elog(NOTICE, "inner_inter %d %d", ARRISNULL( a ), ARRISNULL( b ) );
#endif
- if ( ARRISNULL( a ) || ARRISNULL( b ) ) return NULL;
+ if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
- na = ARRSIZE( a );
- nb = ARRSIZE( b );
+ na = ARRNELEMS( a );
+ nb = ARRNELEMS( b );
da = ARRPTR( a );
db = ARRPTR( b );
r = new_intArrayType( min(na, nb) );
@@ -605,7 +682,7 @@ inner_int_inter ( ArrayType *a, ArrayType *b ) {
if ( (dr - ARRPTR(r)) == 0 ) {
pfree( r );
- return NULL;
+ return new_intArrayType(0);
} else
return resize_intArrayType(r, dr - ARRPTR(r) );
}
@@ -616,7 +693,7 @@ rt__int_size(ArrayType *a, float *size)
if ( ARRISNULL( a ) )
*size = 0.0;
else
- *size = (float)ARRSIZE( a );
+ *size = (float)ARRNELEMS( a );
return;
}
@@ -654,8 +731,7 @@ new_intArrayType( int num ) {
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
r = (ArrayType *) palloc( nbytes );
- if ( ! r )
- elog(ERROR, "Can't allocate memory for new array");
+
MemSet(r, 0, nbytes);
r->size = nbytes;
r->ndim = NDIM;
@@ -672,11 +748,9 @@ static ArrayType *
resize_intArrayType( ArrayType * a, int num ) {
int nbytes = ARR_OVERHEAD( NDIM ) + sizeof(int)*num;
- if ( num == ARRSIZE(a) ) return a;
+ if ( num == ARRNELEMS(a) ) return a;
a = (ArrayType *) repalloc( a, nbytes );
- if ( ! a )
- elog(ERROR, "Can't reallocate memory for new array");
a->size = nbytes;
*( (int*)ARR_DIMS(a) ) = num;
@@ -686,8 +760,8 @@ resize_intArrayType( ArrayType * a, int num ) {
static ArrayType *
copy_intArrayType( ArrayType * a ) {
ArrayType * r;
- if ( ! a ) return NULL;
- r = new_intArrayType( ARRSIZE(a) );
+ if ( ARRISNULL(a) ) return NULL;
+ r = new_intArrayType( ARRNELEMS(a) );
memmove(r,a,VARSIZE(a));
return r;
}
@@ -708,7 +782,7 @@ internal_size (int *a, int len ) {
static ArrayType *
_int_unique( ArrayType * r ) {
int *tmp, *dr, *data;
- int num = ARRSIZE(r);
+ int num = ARRNELEMS(r);
data = tmp = dr = ARRPTR( r );
while( tmp - data < num )
if ( *tmp != *dr )
@@ -721,15 +795,14 @@ _int_unique( ArrayType * r ) {
/*********************************************************************
** intbig functions
*********************************************************************/
-
static void
gensign(BITVEC sign, int * a, int len) {
int i;
- NULLIFY(sign);
- for(i=0; i<len; i++) {
- SETBIT( sign, (*a)%SIGLENBIT );
- a++;
- }
+ /* we assume that the sign vector is previously zeroed */
+ for(i=0; i<len; i++) {
+ SETBIT( sign, (*a)%SIGLENBIT );
+ a++;
+ }
}
static bool
@@ -777,20 +850,13 @@ rt__intbig_size(ArrayType *a, float* sz) {
static ArrayType *
_intbig_union(ArrayType *a, ArrayType *b) {
- ArrayType * r = NULL;
+ ArrayType * r;
BITVECP da, db, dr;
int i;
-
+
if ( ARRISNULL( a ) && ARRISNULL( b ) ) return new_intArrayType(0);
-
- if ( ARRISNULL( a ) ) {
- r = copy_intArrayType( b );
- return r;
- }
- if ( ARRISNULL( b ) ) {
- r = copy_intArrayType( a );
- return r;
- }
+ if ( ARRISNULL( a ) ) return copy_intArrayType( b );
+ if ( ARRISNULL( b ) ) return copy_intArrayType( a );
r = new_intArrayType( SIGLENINT );
@@ -802,14 +868,14 @@ _intbig_union(ArrayType *a, ArrayType *b) {
return r;
}
-/*
+
static ArrayType *
_intbig_inter(ArrayType *a, ArrayType *b) {
- ArrayType * r = NULL;
+ ArrayType * r;
BITVECP da, db, dr;
int i;
-
- if ( ARRISNULL( a ) || ARRISNULL( b ) ) return NULL;
+
+ if ( ARRISNULL( a ) || ARRISNULL( b ) ) return new_intArrayType(0);
r = new_intArrayType( SIGLENINT );
@@ -821,7 +887,7 @@ _intbig_inter(ArrayType *a, ArrayType *b) {
return r;
}
-*/
+
bool *
g_intbig_same(ArrayType *a, ArrayType *b, bool *result) {
BITVECP da, db;
@@ -862,8 +928,6 @@ g_intbig_compress(GISTENTRY *entry) {
if ( ! entry->leafkey ) return entry;
retval = palloc(sizeof(GISTENTRY));
- if ( ! retval )
- elog(ERROR,"Can't allocate memory for compression");
if ( ARRISNULL( in ) ) {
#ifdef PGSQL71
@@ -876,8 +940,8 @@ g_intbig_compress(GISTENTRY *entry) {
r = new_intArrayType( SIGLENINT );
gensign( SIGPTR( r ),
ARRPTR ( in ),
- ARRSIZE( in ) );
-
+ ARRNELEMS( in ) );
+
gistentryinit(*retval, (char *)r, entry->rel, entry->page, entry->offset, VARSIZE( r ), FALSE);
#ifdef PGSQL71
@@ -889,72 +953,28 @@ g_intbig_compress(GISTENTRY *entry) {
GISTENTRY *
g_intbig_decompress(GISTENTRY *entry) {
+#ifdef PGSQL71
+ ArrayType *key;
+ key = (ArrayType *)PG_DETOAST_DATUM( entry->pred );
+ if ( (char*)key != (char*)entry->pred ) {
+ GISTENTRY *retval;
+ retval = palloc(sizeof(GISTENTRY));
+
+ gistentryinit(*retval, (char *)key, entry->rel, entry->page, entry->offset, VARSIZE( key ), FALSE);
+ return retval;
+ }
+#endif
return entry;
}
GIST_SPLITVEC *
g_intbig_picksplit(bytea *entryvec, GIST_SPLITVEC *v) {
+ return _int_common_picksplit( entryvec, v,
+ _intbig_union,
+ _intbig_inter,
+ rt__intbig_size,
+ 1.0);
- OffsetNumber k;
- ArrayType *datum_l, *datum_r, *datum_alpha;
- ArrayType *unionarr;
- float size_l, size_r;
- int nbytes;
- OffsetNumber *left, *right;
- OffsetNumber maxoff;
-
-#ifdef GIST_DEBUG
- elog(NOTICE, "--------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);
- left = v->spl_left;
- v->spl_nleft = 0;
- right = v->spl_right;
- v->spl_nright = 0;
-
- maxoff = OffsetNumberNext(maxoff);
- datum_l = datum_r = NULL;
-
- for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k)) {
- datum_alpha = (ArrayType *)(((GISTENTRY *)(VARDATA(entryvec)))[k].pred);
-
- if ( k != FirstOffsetNumber ) {
- unionarr = (ArrayType *)_intbig_union(datum_l, datum_alpha);
- if ( datum_l ) pfree(datum_l);
- datum_l = unionarr;
- rt__intbig_size((ArrayType *)unionarr, &size_l);
- *left++ = k;
- v->spl_nleft++;
- } else {
- unionarr = (ArrayType *)_intbig_union(datum_r, datum_alpha);
- if ( datum_r ) pfree(datum_r);
- datum_r = unionarr;
- rt__intbig_size((ArrayType *)unionarr, &size_r);
- *right++ = k;
- v->spl_nright++;
- }
- }
-
- if ( *(left-1) > *(right-1) ) {
- *right = FirstOffsetNumber;
- *(left-1) = InvalidOffsetNumber;
- } else {
- *left = FirstOffsetNumber;
- *(right-1) = InvalidOffsetNumber;
- }
-
-
- v->spl_ldatum = (char *)datum_l;
- v->spl_rdatum = (char *)datum_r;
-
-#ifdef GIST_DEBUG
- elog(NOTICE, "--------ENDpicksplit %d %d",v->spl_nleft, v->spl_nright);
-#endif
- return v;
}
ArrayType *
@@ -965,7 +985,6 @@ g_intbig_union(bytea *entryvec, int *sizep) {
float *
g_intbig_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result){
_int_common_penalty( origentry, newentry, result, _intbig_union, rt__intbig_size);
- *result= SIGLENBIT - *result;
return result;
}
@@ -974,13 +993,13 @@ g_intbig_consistent(GISTENTRY *entry, ArrayType *query, StrategyNumber strategy)
bool retval;
ArrayType * q;
+ /* XXX what about toasted input? */
if ( ARRISNULL( query ) ) return FALSE;
q = new_intArrayType( SIGLENINT );
-
gensign( SIGPTR( q ),
ARRPTR( query ),
- ARRSIZE( query ) );
+ ARRNELEMS( query ) );
switch(strategy) {
case RTOverlapStrategyNumber:
@@ -1042,9 +1061,10 @@ _int_common_union(bytea *entryvec, int *sizep, formarray unionf) {
}
-/*
-** The GiST Penalty method for _intments
-*/
+/*****************************************
+ * The GiST Penalty method for _intments *
+ *****************************************/
+
float *
_int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
formarray unionf,
@@ -1063,7 +1083,7 @@ _int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result,
pfree((char *)ud);
#ifdef GIST_DEBUG
- elog(NOTICE, "--penalty\t%g\t%g\t%g", *result, tmp1, tmp2);
+ elog(NOTICE, "--penalty\t%g", *result);
#endif
return(result);
@@ -1078,7 +1098,8 @@ _int_common_picksplit(bytea *entryvec,
GIST_SPLITVEC *v,
formarray unionf,
formarray interf,
- formfloat sizef)
+ formfloat sizef,
+ float coef)
{
OffsetNumber i, j;
ArrayType *datum_alpha, *datum_beta;
@@ -1105,7 +1126,7 @@ _int_common_picksplit(bytea *entryvec,
firsttime = true;
waste = 0.0;
-
+
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) {
datum_alpha = (ArrayType *)(((GISTENTRY *)(VARDATA(entryvec)))[i].pred);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) {
@@ -1137,7 +1158,7 @@ _int_common_picksplit(bytea *entryvec,
}
}
}
-
+
left = v->spl_left;
v->spl_nleft = 0;
right = v->spl_right;
@@ -1163,7 +1184,6 @@ _int_common_picksplit(bytea *entryvec,
*/
maxoff = OffsetNumberNext(maxoff);
-
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
@@ -1192,7 +1212,7 @@ _int_common_picksplit(bytea *entryvec,
(*sizef)((ArrayType *)union_dr, &size_beta);
/* pick which page to add it to */
- if (size_alpha - size_l < size_beta - size_r) {
+ 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;
@@ -1208,7 +1228,6 @@ _int_common_picksplit(bytea *entryvec,
v->spl_nright++;
}
}
- /**left = *right = FirstOffsetNumber;*/ /* sentinel value, see dosplit() */
if ( *(left-1) > *(right-1) ) {
*right = FirstOffsetNumber;
@@ -1218,7 +1237,6 @@ _int_common_picksplit(bytea *entryvec,
*(right-1) = InvalidOffsetNumber;
}
-
v->spl_ldatum = (char *)datum_l;
v->spl_rdatum = (char *)datum_r;