From: Sandro Santilli Date: Wed, 9 Jun 2004 10:19:06 +0000 (+0000) Subject: Moved changes needed for PG75 inside postgis_gist_72.c using #if switches. X-Git-Tag: pgis_0_9_1~176 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=54bceddacda478612c4341d007db50eaae7f90e4;p=postgis Moved changes needed for PG75 inside postgis_gist_72.c using #if switches. git-svn-id: http://svn.osgeo.org/postgis/trunk@618 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/Makefile b/Makefile index cd88e1743..5e1db5812 100644 --- a/Makefile +++ b/Makefile @@ -137,11 +137,7 @@ ifeq ($(USE_VERSION),71) GIST_SUPPORT=71 GIST_ESTIMATE= else - ifeq ($(USE_VERSION),75) - GIST_SUPPORT=75 - else - GIST_SUPPORT=72 - endif + GIST_SUPPORT=72 GIST_ESTIMATE=postgis_estimate.o endif diff --git a/postgis_gist_72.c b/postgis_gist_72.c index e4ee432f4..97ded5c55 100644 --- a/postgis_gist_72.c +++ b/postgis_gist_72.c @@ -11,6 +11,9 @@ * ********************************************************************** * $Log$ + * Revision 1.18 2004/06/09 10:19:06 strk + * Moved changes needed for PG75 inside postgis_gist_72.c using #if switches. + * * Revision 1.17 2004/06/03 08:19:20 strk * yet another Infinite check used: finite() - which checks for NaN,-Inf,+Inf * @@ -84,13 +87,6 @@ #include "postgis.h" #include "utils/elog.h" -//Norman Vine found this problem for compiling under cygwin -// it defines BYTE_ORDER and LITTLE_ENDIAN - -#ifdef __CYGWIN__ -#include // FOR ENDIAN DEFINES -#endif - #define SHOW_DIGS_DOUBLE 15 #define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1) @@ -343,7 +339,11 @@ Datum rtree_decompress(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(gbox_union); Datum gbox_union(PG_FUNCTION_ARGS) { - bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); +#if USE_VERSION < 75 + bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); +#else + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); +#endif int *sizep = (int *) PG_GETARG_POINTER(1); int numranges, i; @@ -355,14 +355,23 @@ Datum gbox_union(PG_FUNCTION_ARGS) fflush( stdout ); #endif +#if USE_VERSION < 75 numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - pageunion = (BOX *) palloc(sizeof(BOX)); cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[0].key); +#else + numranges = entryvec->n; + cur = DatumGetBoxP(entryvec->vector[0].key); +#endif + pageunion = (BOX *) palloc(sizeof(BOX)); memcpy((void *) pageunion, (void *) cur, sizeof(BOX)); for (i = 1; i < numranges; i++) { +#if USE_VERSION < 75 cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); +#else + cur = DatumGetBoxP(entryvec->vector[i].key); +#endif if (pageunion->high.x < cur->high.x) pageunion->high.x = cur->high.x; if (pageunion->low.x > cur->low.x) @@ -429,7 +438,11 @@ PG_FUNCTION_INFO_V1(gbox_picksplit); Datum gbox_picksplit(PG_FUNCTION_ARGS) { - bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); +#if USE_VERSION < 75 + bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); +#else + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); +#endif GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber i; OffsetNumber *listL, @@ -457,15 +470,24 @@ gbox_picksplit(PG_FUNCTION_ARGS) #endif posL = posR = posB = posT = 0; +#if USE_VERSION < 75 maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 1; - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[FirstOffsetNumber].key); +#else + maxoff = entryvec->n - 1; + cur = DatumGetBoxP(entryvec->vector[FirstOffsetNumber].key); +#endif + memcpy((void *) &pageunion, (void *) cur, sizeof(BOX)); /* find MBR */ for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) { +#if USE_VERSION < 75 cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); +#else + cur = DatumGetBoxP(entryvec->vector[i].key); +#endif if ( allisequal == true && ( pageunion.high.x != cur->high.x || pageunion.high.y != cur->high.y || @@ -491,7 +513,11 @@ gbox_picksplit(PG_FUNCTION_ARGS) unionR = (BOX *) palloc(sizeof(BOX)); if (allisequal) { +#if USE_VERSION < 75 cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[OffsetNumberNext(FirstOffsetNumber)].key); +#else + cur = DatumGetBoxP(entryvec->vector[OffsetNumberNext(FirstOffsetNumber)].key); +#endif if (memcmp((void *) cur, (void *) &pageunion, sizeof(BOX)) == 0) { v->spl_left = listL; @@ -540,7 +566,11 @@ gbox_picksplit(PG_FUNCTION_ARGS) for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { +#if USE_VERSION < 75 cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); +#else + cur = DatumGetBoxP(entryvec->vector[i].key); +#endif if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) ADDLIST(listL, unionL, posL,i); else @@ -557,7 +587,11 @@ gbox_picksplit(PG_FUNCTION_ARGS) KBsort *arr = (KBsort*)palloc( sizeof(KBsort) * maxoff ); posL = posR = posB = posT = 0; for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { +#if USE_VERSION < 75 arr[i-1].key = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); +#else + arr[i-1].key = DatumGetBoxP(entryvec->vector[i].key); +#endif arr[i-1].pos = i; } qsort( arr, maxoff, sizeof(KBsort), compare_KB ); diff --git a/postgis_gist_75.c b/postgis_gist_75.c deleted file mode 100644 index 7426c3c5a..000000000 --- a/postgis_gist_75.c +++ /dev/null @@ -1,635 +0,0 @@ -/********************************************************************** - * $Id$ - * - * PostGIS - Spatial Types for PostgreSQL - * http://postgis.refractions.net - * Copyright 2001-2003 Refractions Research Inc. - * - * This is free software; you can redistribute and/or modify it under - * the terms of the GNU General Public Licence. See the COPYING file. - * - ********************************************************************** - * $Log$ - * Revision 1.1 2004/06/09 10:05:07 strk - * initial import - * - ********************************************************************** - * - * GiST indexing functions for pgsql >= 7.5 - * - **********************************************************************/ - -#include "postgres.h" - -#include -#include -#include -#include -#include - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" - -#include "fmgr.h" - -#include "postgis.h" -#include "utils/elog.h" - -#define SHOW_DIGS_DOUBLE 15 -#define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1) - -//#define DEBUG_GIST - -//for GIST index -typedef char* (*BINARY_UNION)(char*, char*, int*); -typedef float (*SIZE_BOX)(char*); -typedef Datum (*RDF)(PG_FUNCTION_ARGS); - - -BOX *convert_box3d_to_box(BOX3D *in); -Datum ggeometry_compress(PG_FUNCTION_ARGS); -Datum ggeometry_consistent(PG_FUNCTION_ARGS); -static bool rtree_internal_consistent(BOX *key, BOX *query,StrategyNumber strategy); -static bool rtree_leaf_consistent(BOX *key, BOX *query,StrategyNumber strategy); -Datum rtree_decompress(PG_FUNCTION_ARGS); -Datum gbox_union(PG_FUNCTION_ARGS); -Datum gbox_picksplit(PG_FUNCTION_ARGS); -Datum gbox_penalty(PG_FUNCTION_ARGS); -Datum gbox_same(PG_FUNCTION_ARGS); -static float size_box(Datum box); -extern void convert_box3d_to_box_p(BOX3D *in,BOX *out); - - -int debug = 0; - -//puts result in pre-allocated "out" -void convert_box3d_to_box_p(BOX3D *in,BOX *out) -{ - - out->high.x = in->URT.x; - out->high.y = in->URT.y; - - out->low.x = in->LLB.x; - out->low.y = in->LLB.y; -} - - -BOX *convert_box3d_to_box(BOX3D *in) -{ - BOX *out = palloc (sizeof (BOX) ); - - out->high.x = in->URT.x; - out->high.y = in->URT.y; - - out->low.x = in->LLB.x; - out->low.y = in->LLB.y; - - return out; -} - -PG_FUNCTION_INFO_V1(ggeometry_compress); -Datum ggeometry_compress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry=(GISTENTRY*)PG_GETARG_POINTER(0); - GISTENTRY *retval; - - if ( entry->leafkey) - { - retval = palloc(sizeof(GISTENTRY)); - if ( DatumGetPointer(entry->key) != NULL ) - { - - GEOMETRY *in; - BOX *r; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: ggeometry_compress called on geometry\n"); - fflush( stdout ); -#endif - - in = (GEOMETRY*)PG_DETOAST_DATUM( entry->key ); - - if (in->nobjs ==0) // this is the EMPTY geometry - { - //elog(NOTICE,"found an empty geometry"); - // dont bother adding this to the index - PG_RETURN_POINTER(entry); - } - - if ( ! finite(in->bvol.URT.x) || - ! finite(in->bvol.URT.y) || - ! finite(in->bvol.LLB.x) || - ! finite(in->bvol.LLB.y) ) - { - //elog(NOTICE, "found infinite geometry"); - PG_RETURN_POINTER(entry); - } - - r = convert_box3d_to_box(&in->bvol); - if ( in != (GEOMETRY*)DatumGetPointer(entry->key) ) - { - pfree( in ); - } - - gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, sizeof(BOX), FALSE); - - } - else - { - gistentryinit(*retval, (Datum) 0, entry->rel, entry->page, - entry->offset, 0,FALSE); - } - } - else - { - retval = entry; - } - PG_RETURN_POINTER(retval); -} - -PG_FUNCTION_INFO_V1(ggeometry_consistent); -Datum ggeometry_consistent(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0); - GEOMETRY *query ; - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - BOX thebox; - bool result; - - /* - ** if entry is not leaf, use rtree_internal_consistent, - ** else use rtree_leaf_consistent - */ - - if ( ( (Pointer *) PG_GETARG_DATUM(1) ) == NULL) - { - //elog(NOTICE,"ggeometry_consistent:: got null query!"); - PG_RETURN_BOOL(false); // null query - this is screwy! - } - - query = (GEOMETRY*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - - - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: ggeometry_consistent called\n"); - fflush( stdout ); -#endif - - if ( ! (DatumGetPointer(entry->key) != NULL && query) ) - PG_RETURN_BOOL(FALSE); - - convert_box3d_to_box_p( &(query->bvol) , &thebox); - - if (GIST_LEAF(entry)) - result = rtree_leaf_consistent((BOX *) DatumGetPointer(entry->key), &thebox, strategy ); - else - result = rtree_internal_consistent((BOX *) DatumGetPointer(entry->key), &thebox, strategy ); - - PG_FREE_IF_COPY(query, 1); - PG_RETURN_BOOL(result); -} - - -static bool -rtree_internal_consistent(BOX *key, - BOX *query, - StrategyNumber strategy) -{ - bool retval; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: rtree_internal_consist called\n"); - fflush( stdout ); -#endif - - switch(strategy) { - case RTLeftStrategyNumber: - case RTOverLeftStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box_overleft, PointerGetDatum(key), PointerGetDatum(query) ) ); - break; - case RTOverlapStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box_overlap, PointerGetDatum(key), PointerGetDatum(query) ) ); - break; - case RTOverRightStrategyNumber: - case RTRightStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box_overright, PointerGetDatum(key), PointerGetDatum(query) ) ); - break; - case RTSameStrategyNumber: - case RTContainsStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box_contain, PointerGetDatum(key), PointerGetDatum(query) ) ); - break; - case RTContainedByStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box_overlap, PointerGetDatum(key), PointerGetDatum(query) ) ); - break; - default: - retval = FALSE; - } - return(retval); -} - - -static bool -rtree_leaf_consistent(BOX *key, - BOX *query, - StrategyNumber strategy) -{ - bool retval; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: rtree_leaf_consist called\n"); - fflush( stdout ); -#endif - - switch (strategy) - { - case RTLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_left, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverlapStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overright, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_right, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTSameStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTContainsStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTContainedByStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_contained, PointerGetDatum(key), PointerGetDatum(query))); - break; - default: - retval = FALSE; - } - return (retval); -} - - -PG_FUNCTION_INFO_V1(rtree_decompress); -Datum rtree_decompress(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); -} - -/* -** The GiST Union method for boxes -** returns the minimal bounding box that encloses all the entries in entryvec -*/ -PG_FUNCTION_INFO_V1(gbox_union); -Datum gbox_union(PG_FUNCTION_ARGS) -{ - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - int *sizep = (int *) PG_GETARG_POINTER(1); - int numranges, - i; - BOX *cur, - *pageunion; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: gbox_union called\n"); - fflush( stdout ); -#endif - - numranges = entryvec->n; - pageunion = (BOX *) palloc(sizeof(BOX)); - cur = DatumGetBoxP(entryvec->vector[0].key); - memcpy((void *) pageunion, (void *) cur, sizeof(BOX)); - - for (i = 1; i < numranges; i++) - { - cur = DatumGetBoxP(entryvec->vector[i].key); - if (pageunion->high.x < cur->high.x) - pageunion->high.x = cur->high.x; - if (pageunion->low.x > cur->low.x) - pageunion->low.x = cur->low.x; - if (pageunion->high.y < cur->high.y) - pageunion->high.y = cur->high.y; - if (pageunion->low.y > cur->low.y) - pageunion->low.y = cur->low.y; - } - *sizep = sizeof(BOX); - - PG_RETURN_POINTER(pageunion); -} - -/* -** The GiST Penalty method for boxes -** As in the R-tree paper, we use change in area as our penalty metric -*/ -PG_FUNCTION_INFO_V1(gbox_penalty); -Datum gbox_penalty(PG_FUNCTION_ARGS) -{ - GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *result = (float *) PG_GETARG_POINTER(2); - Datum ud; - float tmp1; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: gbox_penalty called\n"); - fflush( stdout ); -#endif - - ud = DirectFunctionCall2(rt_box_union, origentry->key, newentry->key); - tmp1 = size_box(ud); - if (DatumGetPointer(ud) != NULL) - pfree(DatumGetPointer(ud)); - - *result = tmp1 - size_box(origentry->key); - PG_RETURN_POINTER(result); -} - -typedef struct { - BOX *key; - int pos; -} KBsort; - -static int -compare_KB(const void* a, const void* b) { - BOX *abox = ((KBsort*)a)->key; - BOX *bbox = ((KBsort*)b)->key; - float sa = (abox->high.x - abox->low.x) * (abox->high.y - abox->low.y); - float sb = (bbox->high.x - bbox->low.x) * (bbox->high.y - bbox->low.y); - - if ( sa==sb ) return 0; - return ( sa>sb ) ? 1 : -1; -} - -/* -** The GiST PickSplit method -** New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree', -** C.H.Ang and T.C.Tan -*/ -PG_FUNCTION_INFO_V1(gbox_picksplit); -Datum -gbox_picksplit(PG_FUNCTION_ARGS) -{ - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - OffsetNumber i; - OffsetNumber *listL, - *listR, - *listB, - *listT; - BOX *unionL, - *unionR, - *unionB, - *unionT; - int posL, - posR, - posB, - posT; - BOX pageunion; - BOX *cur; - char direction = ' '; - bool allisequal = true; - OffsetNumber maxoff; - int nbytes; - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: gbox_picksplit called\n"); - fflush( stdout ); -#endif - - posL = posR = posB = posT = 0; - maxoff = entryvec->n - 1; - - cur = DatumGetBoxP(entryvec->vector[FirstOffsetNumber].key); - memcpy((void *) &pageunion, (void *) cur, sizeof(BOX)); - - /* find MBR */ - for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) - { - cur = DatumGetBoxP(entryvec->vector[i].key); - if ( allisequal == true && ( - pageunion.high.x != cur->high.x || - pageunion.high.y != cur->high.y || - pageunion.low.x != cur->low.x || - pageunion.low.y != cur->low.y - ) ) - allisequal = false; - - if (pageunion.high.x < cur->high.x) - pageunion.high.x = cur->high.x; - if (pageunion.low.x > cur->low.x) - pageunion.low.x = cur->low.x; - if (pageunion.high.y < cur->high.y) - pageunion.high.y = cur->high.y; - if (pageunion.low.y > cur->low.y) - pageunion.low.y = cur->low.y; - } - - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - listL = (OffsetNumber *) palloc(nbytes); - listR = (OffsetNumber *) palloc(nbytes); - unionL = (BOX *) palloc(sizeof(BOX)); - unionR = (BOX *) palloc(sizeof(BOX)); - if (allisequal) - { - cur = DatumGetBoxP(entryvec->vector[OffsetNumberNext(FirstOffsetNumber)].key); - if (memcmp((void *) cur, (void *) &pageunion, sizeof(BOX)) == 0) - { - v->spl_left = listL; - v->spl_right = listR; - v->spl_nleft = v->spl_nright = 0; - memcpy((void *) unionL, (void *) &pageunion, sizeof(BOX)); - memcpy((void *) unionR, (void *) &pageunion, sizeof(BOX)); - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - if (i <= (maxoff - FirstOffsetNumber + 1) / 2) - { - v->spl_left[v->spl_nleft] = i; - v->spl_nleft++; - } - else - { - v->spl_right[v->spl_nright] = i; - v->spl_nright++; - } - } - v->spl_ldatum = BoxPGetDatum(unionL); - v->spl_rdatum = BoxPGetDatum(unionR); - - PG_RETURN_POINTER(v); - } - } - - listB = (OffsetNumber *) palloc(nbytes); - listT = (OffsetNumber *) palloc(nbytes); - unionB = (BOX *) palloc(sizeof(BOX)); - unionT = (BOX *) palloc(sizeof(BOX)); - -#define ADDLIST( list, unionD, pos, num ) do { \ - if ( pos ) { \ - if ( unionD->high.x < cur->high.x ) unionD->high.x = cur->high.x; \ - if ( unionD->low.x > cur->low.x ) unionD->low.x = cur->low.x; \ - if ( unionD->high.y < cur->high.y ) unionD->high.y = cur->high.y; \ - if ( unionD->low.y > cur->low.y ) unionD->low.y = cur->low.y; \ - } else { \ - memcpy( (void*)unionD, (void*) cur, sizeof( BOX ) ); \ - } \ - list[pos] = num; \ - (pos)++; \ -} while(0) - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - cur = DatumGetBoxP(entryvec->vector[i].key); - if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) - ADDLIST(listL, unionL, posL,i); - else - ADDLIST(listR, unionR, posR,i); - if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y) - ADDLIST(listB, unionB, posB,i); - else - ADDLIST(listT, unionT, posT,i); - } - - /* bad disposition, sort by ascending and resplit */ - if ( (posR==0 || posL==0) && (posT==0 || posB==0) ) { - KBsort *arr = (KBsort*)palloc( sizeof(KBsort) * maxoff ); - posL = posR = posB = posT = 0; - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - arr[i-1].key = DatumGetBoxP(entryvec->vector[i].key); - arr[i-1].pos = i; - } - qsort( arr, maxoff, sizeof(KBsort), compare_KB ); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - cur = arr[i-1].key; - if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) - ADDLIST(listL, unionL, posL,arr[i-1].pos); - else if ( cur->low.x - pageunion.low.x > pageunion.high.x - cur->high.x ) - ADDLIST(listR, unionR, posR,arr[i-1].pos); - else - { - if ( posL>posR ) - ADDLIST(listR, unionR, posR,arr[i-1].pos); - else - ADDLIST(listL, unionL, posL,arr[i-1].pos); - } - - if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y) - ADDLIST(listB, unionB, posB,arr[i-1].pos); - else if ( cur->low.y - pageunion.low.y > pageunion.high.y - cur->high.y ) - ADDLIST(listT, unionT, posT,arr[i-1].pos); - else - { - if ( posB>posT ) - ADDLIST(listT, unionT, posT,arr[i-1].pos); - else - ADDLIST(listB, unionB, posB,arr[i-1].pos); - } - } - pfree(arr); - } - - /* which split more optimal? */ - if (Max(posL, posR) < Max(posB, posT)) - direction = 'x'; - else if (Max(posL, posR) > Max(posB, posT)) - direction = 'y'; - else - { - Datum interLR = DirectFunctionCall2(rt_box_inter, - BoxPGetDatum(unionL), - BoxPGetDatum(unionR)); - Datum interBT = DirectFunctionCall2(rt_box_inter, - BoxPGetDatum(unionB), - BoxPGetDatum(unionT)); - float sizeLR, - sizeBT; - - sizeLR = size_box(interLR); - sizeBT = size_box(interBT); - - if (sizeLR < sizeBT) - direction = 'x'; - else - direction = 'y'; - } - - if (direction == 'x') - { - pfree(unionB); - pfree(listB); - pfree(unionT); - pfree(listT); - - v->spl_left = listL; - v->spl_right = listR; - v->spl_nleft = posL; - v->spl_nright = posR; - v->spl_ldatum = BoxPGetDatum(unionL); - v->spl_rdatum = BoxPGetDatum(unionR); - } - else - { - pfree(unionR); - pfree(listR); - pfree(unionL); - pfree(listL); - - v->spl_left = listB; - v->spl_right = listT; - v->spl_nleft = posB; - v->spl_nright = posT; - v->spl_ldatum = BoxPGetDatum(unionB); - v->spl_rdatum = BoxPGetDatum(unionT); - } - - PG_RETURN_POINTER(v); -} - -/* -** Equality method -*/ -PG_FUNCTION_INFO_V1(gbox_same); -Datum gbox_same(PG_FUNCTION_ARGS) -{ - BOX *b1 = (BOX *) PG_GETARG_POINTER(0); - BOX *b2 = (BOX *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: gbox_same called\n"); - fflush( stdout ); -#endif - - if (b1 && b2) - *result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2))); - else - *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE; - PG_RETURN_POINTER(result); -} - -static float -size_box(Datum box) -{ - -#ifdef DEBUG_GIST - elog(NOTICE,"GIST: size_box called\n"); - fflush( stdout ); -#endif - - if (DatumGetPointer(box) != NULL) - { - float size; - - DirectFunctionCall2(rt_box_size, - box, PointerGetDatum(&size)); - return size; - } - else - return 0.0; -}