summaryrefslogtreecommitdiff
path: root/contrib/cube/cube.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cube/cube.c')
-rw-r--r--contrib/cube/cube.c1750
1 files changed, 936 insertions, 814 deletions
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index 35ac34f0b0..4d6169a480 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -16,67 +16,67 @@
#include "cubedata.h"
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define abs(a) ((a) < (0) ? (-a) : (a))
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) <= (b) ? (a) : (b))
+#define abs(a) ((a) < (0) ? (-a) : (a))
-extern void set_parse_buffer(char *str);
-extern int cube_yyparse();
+extern void set_parse_buffer(char *str);
+extern int cube_yyparse();
/*
** Input/Output routines
*/
-NDBOX * cube_in(char *str);
-char * cube_out(NDBOX *cube);
+NDBOX *cube_in(char *str);
+char *cube_out(NDBOX * cube);
-/*
+/*
** GiST support methods
*/
-bool g_cube_consistent(GISTENTRY *entry, NDBOX *query, StrategyNumber strategy);
-GISTENTRY * g_cube_compress(GISTENTRY *entry);
-GISTENTRY * g_cube_decompress(GISTENTRY *entry);
-float * g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
-GIST_SPLITVEC * g_cube_picksplit(bytea *entryvec, GIST_SPLITVEC *v);
-bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
-bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
-NDBOX * g_cube_union(bytea *entryvec, int *sizep);
-NDBOX * g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep);
-bool * g_cube_same(NDBOX *b1, NDBOX *b2, bool *result);
+bool g_cube_consistent(GISTENTRY *entry, NDBOX * query, StrategyNumber strategy);
+GISTENTRY *g_cube_compress(GISTENTRY *entry);
+GISTENTRY *g_cube_decompress(GISTENTRY *entry);
+float *g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
+GIST_SPLITVEC *g_cube_picksplit(bytea *entryvec, GIST_SPLITVEC *v);
+bool g_cube_leaf_consistent(NDBOX * key, NDBOX * query, StrategyNumber strategy);
+bool g_cube_internal_consistent(NDBOX * key, NDBOX * query, StrategyNumber strategy);
+NDBOX *g_cube_union(bytea *entryvec, int *sizep);
+NDBOX *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep);
+bool *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result);
/*
** R-tree suport functions
*/
-bool cube_same(NDBOX *a, NDBOX *b);
-bool cube_different(NDBOX *a, NDBOX *b);
-bool cube_contains(NDBOX *a, NDBOX *b);
-bool cube_contained (NDBOX *a, NDBOX *b);
-bool cube_overlap(NDBOX *a, NDBOX *b);
-NDBOX * cube_union(NDBOX *a, NDBOX *b);
-NDBOX * cube_inter(NDBOX *a, NDBOX *b);
-float * cube_size(NDBOX *a);
-void rt_cube_size(NDBOX *a, float *sz);
+bool cube_same(NDBOX * a, NDBOX * b);
+bool cube_different(NDBOX * a, NDBOX * b);
+bool cube_contains(NDBOX * a, NDBOX * b);
+bool cube_contained(NDBOX * a, NDBOX * b);
+bool cube_overlap(NDBOX * a, NDBOX * b);
+NDBOX *cube_union(NDBOX * a, NDBOX * b);
+NDBOX *cube_inter(NDBOX * a, NDBOX * b);
+float *cube_size(NDBOX * a);
+void rt_cube_size(NDBOX * a, float *sz);
/*
** These make no sense for this type, but R-tree wants them
*/
-bool cube_over_left(NDBOX *a, NDBOX *b);
-bool cube_over_right(NDBOX *a, NDBOX *b);
-bool cube_left(NDBOX *a, NDBOX *b);
-bool cube_right(NDBOX *a, NDBOX *b);
+bool cube_over_left(NDBOX * a, NDBOX * b);
+bool cube_over_right(NDBOX * a, NDBOX * b);
+bool cube_left(NDBOX * a, NDBOX * b);
+bool cube_right(NDBOX * a, NDBOX * b);
/*
** miscellaneous
*/
-bool cube_lt(NDBOX *a, NDBOX *b);
-bool cube_gt(NDBOX *a, NDBOX *b);
-float * cube_distance(NDBOX *a, NDBOX *b);
+bool cube_lt(NDBOX * a, NDBOX * b);
+bool cube_gt(NDBOX * a, NDBOX * b);
+float *cube_distance(NDBOX * a, NDBOX * b);
-/*
+/*
** Auxiliary funxtions
*/
-static float distance_1D(float a1, float a2, float b1, float b2);
-static NDBOX *swap_corners (NDBOX *a);
+static float distance_1D(float a1, float a2, float b1, float b2);
+static NDBOX *swap_corners(NDBOX * a);
/*****************************************************************************
@@ -88,68 +88,71 @@ static NDBOX *swap_corners (NDBOX *a);
NDBOX *
cube_in(char *str)
{
- void * result;
+ void *result;
- set_parse_buffer( str );
+ set_parse_buffer(str);
- if ( cube_yyparse(&result) != 0 ) {
- return NULL;
- }
+ if (cube_yyparse(&result) != 0)
+ return NULL;
- return ( (NDBOX *)result );
+ return ((NDBOX *) result);
}
/*
* You might have noticed a slight inconsistency between the following
* declaration and the SQL definition:
- * CREATE FUNCTION cube_out(opaque) RETURNS opaque ...
+ * CREATE FUNCTION cube_out(opaque) RETURNS opaque ...
* The reason is that the argument pass into cube_out is really just a
* pointer. POSTGRES thinks all output functions are:
- * char *out_func(char *);
+ * char *out_func(char *);
*/
char *
-cube_out(NDBOX *cube)
+cube_out(NDBOX * cube)
{
- char *result;
- char *p;
- int equal = 1;
- int dim = cube->dim;
- int i;
-
- if (cube == NULL)
- return(NULL);
-
- p = result = (char *) palloc(100);
-
- /* while printing the first (LL) corner, check if it is equal
- to the scond one */
- p += sprintf(p, "(");
- for ( i=0; i < dim; i++ ) {
- p += sprintf(p, "%g", cube->x[i]);
- p += sprintf(p, ", ");
- if ( cube->x[i] != cube->x[i+dim] ) {
- equal = 0;
- }
- }
- p -= 2; /* get rid of the last ", " */
- p += sprintf(p, ")");
-
- if ( !equal ) {
- p += sprintf(p, ",(");
- for ( i=dim; i < dim * 2; i++ ) {
- p += sprintf(p, "%g", cube->x[i]);
- p += sprintf(p, ", ");
- }
- p -= 2;
- p += sprintf(p, ")");
- }
-
- return(result);
+ char *result;
+ char *p;
+ int equal = 1;
+ int dim = cube->dim;
+ int i;
+
+ if (cube == NULL)
+ return (NULL);
+
+ p = result = (char *) palloc(100);
+
+ /*
+ * while printing the first (LL) corner, check if it is equal to the
+ * scond one
+ */
+ p += sprintf(p, "(");
+ for (i = 0; i < dim; i++)
+ {
+ p += sprintf(p, "%g", cube->x[i]);
+ p += sprintf(p, ", ");
+ if (cube->x[i] != cube->x[i + dim])
+ equal = 0;
+ }
+ p -= 2; /* get rid of the last ", " */
+ p += sprintf(p, ")");
+
+ if (!equal)
+ {
+ p += sprintf(p, ",(");
+ for (i = dim; i < dim * 2; i++)
+ {
+ p += sprintf(p, "%g", cube->x[i]);
+ p += sprintf(p, ", ");
+ }
+ p -= 2;
+ p += sprintf(p, ")");
+ }
+
+ return (result);
}
/*****************************************************************************
- * GiST functions
+ * GiST functions
*****************************************************************************/
/*
@@ -158,19 +161,20 @@ cube_out(NDBOX *cube)
** the predicate x op query == FALSE, where op is the oper
** corresponding to strategy in the pg_amop table.
*/
-bool
+bool
g_cube_consistent(GISTENTRY *entry,
- NDBOX *query,
- StrategyNumber strategy)
+ NDBOX * query,
+ StrategyNumber strategy)
{
- /*
- ** if entry is not leaf, use g_cube_internal_consistent,
- ** else use g_cube_leaf_consistent
- */
- if (GIST_LEAF(entry))
- return(g_cube_leaf_consistent((NDBOX *)(entry->pred), query, strategy));
- else
- return(g_cube_internal_consistent((NDBOX *)(entry->pred), query, strategy));
+
+ /*
+ * * if entry is not leaf, use g_cube_internal_consistent, * else use
+ * g_cube_leaf_consistent
+ */
+ if (GIST_LEAF(entry))
+ return (g_cube_leaf_consistent((NDBOX *) (entry->pred), query, strategy));
+ else
+ return (g_cube_internal_consistent((NDBOX *) (entry->pred), query, strategy));
}
@@ -181,48 +185,55 @@ g_cube_consistent(GISTENTRY *entry,
NDBOX *
g_cube_union(bytea *entryvec, int *sizep)
{
- int numranges, i;
- NDBOX *out = (NDBOX *)NULL;
- NDBOX *tmp;
-
- /*
- fprintf(stderr, "union\n");
- */
- numranges = (VARSIZE(entryvec) - VARHDRSZ)/sizeof(GISTENTRY);
- tmp = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[0]).pred;
- /*
- *sizep = sizeof(NDBOX); -- NDBOX has variable size
- */
- *sizep = tmp->size;
-
- for (i = 1; i < numranges; i++) {
- out = g_cube_binary_union(tmp, (NDBOX *)
- (((GISTENTRY *)(VARDATA(entryvec)))[i]).pred,
- sizep);
- /*
- fprintf(stderr, "\t%s ^ %s -> %s\n", cube_out(tmp), cube_out((NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[i]).pred), cube_out(out));
- */
- if (i > 1) pfree(tmp);
- tmp = out;
- }
-
- return(out);
+ int numranges,
+ i;
+ NDBOX *out = (NDBOX *) NULL;
+ NDBOX *tmp;
+
+ /*
+ * fprintf(stderr, "union\n");
+ */
+ numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
+ tmp = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred;
+
+ /*
+ * sizep = sizeof(NDBOX); -- NDBOX has variable size
+ */
+ *sizep = tmp->size;
+
+ for (i = 1; i < numranges; i++)
+ {
+ out = g_cube_binary_union(tmp, (NDBOX *)
+ (((GISTENTRY *) (VARDATA(entryvec)))[i]).pred,
+ sizep);
+
+ /*
+ * fprintf(stderr, "\t%s ^ %s -> %s\n", cube_out(tmp),
+ * cube_out((NDBOX *)(((GISTENTRY
+ * *)(VARDATA(entryvec)))[i]).pred), cube_out(out));
+ */
+ if (i > 1)
+ pfree(tmp);
+ tmp = out;
+ }
+
+ return (out);
}
/*
** GiST Compress and Decompress methods for boxes
** do not do anything.
*/
-GISTENTRY *
+GISTENTRY *
g_cube_compress(GISTENTRY *entry)
{
- return(entry);
+ return (entry);
}
-GISTENTRY *
+GISTENTRY *
g_cube_decompress(GISTENTRY *entry)
{
- return(entry);
+ return (entry);
}
/*
@@ -232,398 +243,448 @@ g_cube_decompress(GISTENTRY *entry)
float *
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{
- Datum ud;
- float tmp1, tmp2;
-
- ud = (Datum)cube_union((NDBOX *)(origentry->pred), (NDBOX *)(newentry->pred));
- rt_cube_size((NDBOX *)ud, &tmp1);
- rt_cube_size((NDBOX *)(origentry->pred), &tmp2);
- *result = tmp1 - tmp2;
- pfree((char *)ud);
- /*
- fprintf(stderr, "penalty\n");
- fprintf(stderr, "\t%g\n", *result);
- */
- return(result);
+ Datum ud;
+ float tmp1,
+ tmp2;
+
+ ud = (Datum) cube_union((NDBOX *) (origentry->pred), (NDBOX *) (newentry->pred));
+ rt_cube_size((NDBOX *) ud, &tmp1);
+ rt_cube_size((NDBOX *) (origentry->pred), &tmp2);
+ *result = tmp1 - tmp2;
+ pfree((char *) ud);
+
+ /*
+ * fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result);
+ */
+ return (result);
}
/*
** The GiST PickSplit method for boxes
-** We use Guttman's poly time split algorithm
+** We use Guttman's poly time split algorithm
*/
GIST_SPLITVEC *
g_cube_picksplit(bytea *entryvec,
- GIST_SPLITVEC *v)
+ GIST_SPLITVEC *v)
{
- OffsetNumber i, j;
- NDBOX *datum_alpha, *datum_beta;
- NDBOX *datum_l, *datum_r;
- NDBOX *union_d, *union_dl, *union_dr;
- NDBOX *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;
-
- /*
- fprintf(stderr, "picksplit\n");
- */
- 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 = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[i].pred);
- for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) {
- datum_beta = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[j].pred);
-
- /* compute the wasted space by unioning these guys */
- /* size_waste = size_union - size_inter; */
- union_d = (NDBOX *)cube_union(datum_alpha, datum_beta);
- rt_cube_size(union_d, &size_union);
- inter_d = (NDBOX *)cube_inter(datum_alpha, datum_beta);
- rt_cube_size(inter_d, &size_inter);
- size_waste = size_union - size_inter;
-
- pfree(union_d);
-
- if (inter_d != (NDBOX *) NULL)
- pfree(inter_d);
-
- /*
- * are these a more promising split than 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;
-
- datum_alpha = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[seed_1].pred);
- datum_l = (NDBOX *)cube_union(datum_alpha, datum_alpha);
- rt_cube_size((NDBOX *)datum_l, &size_l);
- datum_beta = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[seed_2].pred);;
- datum_r = (NDBOX *)cube_union(datum_beta, datum_beta);
- rt_cube_size((NDBOX *)datum_r, &size_r);
-
- /*
- * 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.
- */
-
- maxoff = OffsetNumberNext(maxoff);
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
-
+ OffsetNumber i,
+ j;
+ NDBOX *datum_alpha,
+ *datum_beta;
+ NDBOX *datum_l,
+ *datum_r;
+ NDBOX *union_d,
+ *union_dl,
+ *union_dr;
+ NDBOX *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;
+
/*
- * 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.
+ * fprintf(stderr, "picksplit\n");
*/
-
- if (i == seed_1) {
- *left++ = i;
- v->spl_nleft++;
- continue;
- } else if (i == seed_2) {
- *right++ = i;
- v->spl_nright++;
- continue;
+ 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 = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred);
+ for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
+ {
+ datum_beta = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred);
+
+ /* compute the wasted space by unioning these guys */
+ /* size_waste = size_union - size_inter; */
+ union_d = (NDBOX *) cube_union(datum_alpha, datum_beta);
+ rt_cube_size(union_d, &size_union);
+ inter_d = (NDBOX *) cube_inter(datum_alpha, datum_beta);
+ rt_cube_size(inter_d, &size_inter);
+ size_waste = size_union - size_inter;
+
+ pfree(union_d);
+
+ if (inter_d != (NDBOX *) NULL)
+ pfree(inter_d);
+
+ /*
+ * are these a more promising split than what we've already
+ * seen?
+ */
+
+ if (size_waste > waste || firsttime)
+ {
+ waste = size_waste;
+ seed_1 = i;
+ seed_2 = j;
+ firsttime = false;
+ }
+ }
}
-
- /* okay, which page needs least enlargement? */
- datum_alpha = (NDBOX *)(((GISTENTRY *)(VARDATA(entryvec)))[i].pred);
- union_dl = (NDBOX *)cube_union(datum_l, datum_alpha);
- union_dr = (NDBOX *)cube_union(datum_r, datum_alpha);
- rt_cube_size((NDBOX *)union_dl, &size_alpha);
- rt_cube_size((NDBOX *)union_dr, &size_beta);
-
- /* pick which page to add it to */
- if (size_alpha - size_l < size_beta - size_r) {
- pfree(datum_l);
- pfree(union_dr);
- datum_l = union_dl;
- size_l = size_alpha;
- *left++ = i;
- v->spl_nleft++;
- } else {
- pfree(datum_r);
- pfree(union_dl);
- datum_r = union_dr;
- size_r = size_alpha;
- *right++ = i;
- v->spl_nright++;
+
+ left = v->spl_left;
+ v->spl_nleft = 0;
+ right = v->spl_right;
+ v->spl_nright = 0;
+
+ datum_alpha = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred);
+ datum_l = (NDBOX *) cube_union(datum_alpha, datum_alpha);
+ rt_cube_size((NDBOX *) datum_l, &size_l);
+ datum_beta = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred);;
+ datum_r = (NDBOX *) cube_union(datum_beta, datum_beta);
+ rt_cube_size((NDBOX *) datum_r, &size_r);
+
+ /*
+ * 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.
+ */
+
+ maxoff = OffsetNumberNext(maxoff);
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+
+ /*
+ * 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 = (NDBOX *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred);
+ union_dl = (NDBOX *) cube_union(datum_l, datum_alpha);
+ union_dr = (NDBOX *) cube_union(datum_r, datum_alpha);
+ rt_cube_size((NDBOX *) union_dl, &size_alpha);
+ rt_cube_size((NDBOX *) union_dr, &size_beta);
+
+ /* pick which page to add it to */
+ if (size_alpha - size_l < size_beta - size_r)
+ {
+ pfree(datum_l);
+ pfree(union_dr);
+ datum_l = union_dl;
+ size_l = size_alpha;
+ *left++ = i;
+ v->spl_nleft++;
+ }
+ else
+ {
+ pfree(datum_r);
+ pfree(union_dl);
+ datum_r = union_dr;
+ size_r = size_alpha;
+ *right++ = i;
+ v->spl_nright++;
+ }
}
- }
- *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
-
- v->spl_ldatum = (char *)datum_l;
- v->spl_rdatum = (char *)datum_r;
+ *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
- return v;
+ v->spl_ldatum = (char *) datum_l;
+ v->spl_rdatum = (char *) datum_r;
+
+ return v;
}
/*
** Equality method
*/
bool *
-g_cube_same(NDBOX *b1, NDBOX *b2, bool *result)
+g_cube_same(NDBOX * b1, NDBOX * b2, bool *result)
{
- if (cube_same(b1, b2))
- *result = TRUE;
- else *result = FALSE;
- /*
- fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
- */
- return(result);
+ if (cube_same(b1, b2))
+ *result = TRUE;
+ else
+ *result = FALSE;
+
+ /*
+ * fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
+ */
+ return (result);
}
-/*
+/*
** SUPPORT ROUTINES
*/
-bool
-g_cube_leaf_consistent(NDBOX *key,
- NDBOX *query,
- StrategyNumber strategy)
+bool
+g_cube_leaf_consistent(NDBOX * key,
+ NDBOX * query,
+ StrategyNumber strategy)
{
- bool retval;
-
- /*
- fprintf(stderr, "leaf_consistent, %d\n", strategy);
- */
- switch(strategy) {
- case RTLeftStrategyNumber:
- retval = (bool)cube_left(key, query);
- break;
- case RTOverLeftStrategyNumber:
- retval = (bool)cube_over_left(key,query);
- break;
- case RTOverlapStrategyNumber:
- retval = (bool)cube_overlap(key, query);
- break;
- case RTOverRightStrategyNumber:
- retval = (bool)cube_over_right(key, query);
- break;
- case RTRightStrategyNumber:
- retval = (bool)cube_right(key, query);
- break;
- case RTSameStrategyNumber:
- retval = (bool)cube_same(key, query);
- break;
- case RTContainsStrategyNumber:
- retval = (bool)cube_contains(key, query);
- break;
- case RTContainedByStrategyNumber:
- retval = (bool)cube_contained(key,query);
- break;
- default:
- retval = FALSE;
- }
- return(retval);
+ bool retval;
+
+ /*
+ * fprintf(stderr, "leaf_consistent, %d\n", strategy);
+ */
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ retval = (bool) cube_left(key, query);
+ break;
+ case RTOverLeftStrategyNumber:
+ retval = (bool) cube_over_left(key, query);
+ break;
+ case RTOverlapStrategyNumber:
+ retval = (bool) cube_overlap(key, query);
+ break;
+ case RTOverRightStrategyNumber:
+ retval = (bool) cube_over_right(key, query);
+ break;
+ case RTRightStrategyNumber:
+ retval = (bool) cube_right(key, query);
+ break;
+ case RTSameStrategyNumber:
+ retval = (bool) cube_same(key, query);
+ break;
+ case RTContainsStrategyNumber:
+ retval = (bool) cube_contains(key, query);
+ break;
+ case RTContainedByStrategyNumber:
+ retval = (bool) cube_contained(key, query);
+ break;
+ default:
+ retval = FALSE;
+ }
+ return (retval);
}
-bool
-g_cube_internal_consistent(NDBOX *key,
- NDBOX *query,
- StrategyNumber strategy)
+bool
+g_cube_internal_consistent(NDBOX * key,
+ NDBOX * query,
+ StrategyNumber strategy)
{
- bool retval;
-
- /*
- fprintf(stderr, "internal_consistent, %d\n", strategy);
- */
- switch(strategy) {
- case RTLeftStrategyNumber:
- case RTOverLeftStrategyNumber:
- retval = (bool)cube_over_left(key,query);
- break;
- case RTOverlapStrategyNumber:
- retval = (bool)cube_overlap(key, query);
- break;
- case RTOverRightStrategyNumber:
- case RTRightStrategyNumber:
- retval = (bool)cube_right(key, query);
- break;
- case RTSameStrategyNumber:
- case RTContainsStrategyNumber:
- retval = (bool)cube_contains(key, query);
- break;
- case RTContainedByStrategyNumber:
- retval = (bool)cube_overlap(key, query);
- break;
- default:
- retval = FALSE;
- }
- return(retval);
+ bool retval;
+
+ /*
+ * fprintf(stderr, "internal_consistent, %d\n", strategy);
+ */
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ case RTOverLeftStrategyNumber:
+ retval = (bool) cube_over_left(key, query);
+ break;
+ case RTOverlapStrategyNumber:
+ retval = (bool) cube_overlap(key, query);
+ break;
+ case RTOverRightStrategyNumber:
+ case RTRightStrategyNumber:
+ retval = (bool) cube_right(key, query);
+ break;
+ case RTSameStrategyNumber:
+ case RTContainsStrategyNumber:
+ retval = (bool) cube_contains(key, query);
+ break;
+ case RTContainedByStrategyNumber:
+ retval = (bool) cube_overlap(key, query);
+ break;
+ default:
+ retval = FALSE;
+ }
+ return (retval);
}
NDBOX *
-g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)
+g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep)
{
- NDBOX *retval;
+ NDBOX *retval;
- retval = cube_union(r1, r2);
- *sizep = retval->size;
+ retval = cube_union(r1, r2);
+ *sizep = retval->size;
- return (retval);
+ return (retval);
}
/* cube_union */
-NDBOX *cube_union(NDBOX *box_a, NDBOX *box_b)
+NDBOX *
+cube_union(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- NDBOX *result;
- NDBOX *a = swap_corners(box_a);
- NDBOX *b = swap_corners(box_b);
-
- if ( a->dim >= b->dim ) {
- result = palloc(a->size);
- result->size = a->size;
- result->dim = a->dim;
- }
- else {
- result = palloc(b->size);
- result->size = b->size;
- result->dim = b->dim;
- }
-
- /* swap the box pointers if needed */
- if ( a->dim < b->dim ) {
- NDBOX * tmp = b; b = a; a = tmp;
- }
-
- /* use the potentially smaller of the two boxes (b) to fill in
- the result, padding absent dimensions with zeroes*/
- for ( i = 0; i < b->dim; i++ ) {
- result->x[i] = b->x[i];
- result->x[i + a->dim] = b->x[i + b->dim];
- }
- for ( i = b->dim; i < a->dim; i++ ) {
- result->x[i] = 0;
- result->x[i + a->dim] = 0;
- }
-
- /* compute the union */
- for ( i = 0; i < a->dim; i++ ) {
- result->x[i] = min(a->x[i], result->x[i]);
- }
- for ( i = a->dim; i < a->dim * 2; i++ ) {
- result->x[i] = max(a->x[i], result->x[i]);
- }
-
- pfree(a);
- pfree(b);
-
- return(result);
+ int i;
+ NDBOX *result;
+ NDBOX *a = swap_corners(box_a);
+ NDBOX *b = swap_corners(box_b);
+
+ if (a->dim >= b->dim)
+ {
+ result = palloc(a->size);
+ result->size = a->size;
+ result->dim = a->dim;
+ }
+ else
+ {
+ result = palloc(b->size);
+ result->size = b->size;
+ result->dim = b->dim;
+ }
+
+ /* swap the box pointers if needed */
+ if (a->dim < b->dim)
+ {
+ NDBOX *tmp = b;
+
+ b = a;
+ a = tmp;
+ }
+
+ /*
+ * use the potentially smaller of the two boxes (b) to fill in the
+ * result, padding absent dimensions with zeroes
+ */
+ for (i = 0; i < b->dim; i++)
+ {
+ result->x[i] = b->x[i];
+ result->x[i + a->dim] = b->x[i + b->dim];
+ }
+ for (i = b->dim; i < a->dim; i++)
+ {
+ result->x[i] = 0;
+ result->x[i + a->dim] = 0;
+ }
+
+ /* compute the union */
+ for (i = 0; i < a->dim; i++)
+ result->x[i] = min(a->x[i], result->x[i]);
+ for (i = a->dim; i < a->dim * 2; i++)
+ result->x[i] = max(a->x[i], result->x[i]);
+
+ pfree(a);
+ pfree(b);
+
+ return (result);
}
/* cube_inter */
-NDBOX *cube_inter(NDBOX *box_a, NDBOX *box_b)
+NDBOX *
+cube_inter(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- NDBOX * result;
- NDBOX *a = swap_corners(box_a);
- NDBOX *b = swap_corners(box_b);
-
- if ( a->dim >= b->dim ) {
- result = palloc(a->size);
- result->size = a->size;
- result->dim = a->dim;
- }
- else {
- result = palloc(b->size);
- result->size = b->size;
- result->dim = b->dim;
- }
-
- /* swap the box pointers if needed */
- if ( a->dim < b->dim ) {
- NDBOX * tmp = b; b = a; a = tmp;
- }
-
- /* use the potentially smaller of the two boxes (b) to fill in
- the result, padding absent dimensions with zeroes*/
- for ( i = 0; i < b->dim; i++ ) {
- result->x[i] = b->x[i];
- result->x[i + a->dim] = b->x[i + b->dim];
- }
- for ( i = b->dim; i < a->dim; i++ ) {
- result->x[i] = 0;
- result->x[i + a->dim] = 0;
- }
-
- /* compute the intersection */
- for ( i = 0; i < a->dim; i++ ) {
- result->x[i] = max(a->x[i], result->x[i]);
- }
- for ( i = a->dim; i < a->dim * 2; i++ ) {
- result->x[i] = min(a->x[i], result->x[i]);
- }
-
- pfree(a);
- pfree(b);
-
- /* Is it OK to return a non-null intersection for non-overlapping boxes? */
- return(result);
+ int i;
+ NDBOX *result;
+ NDBOX *a = swap_corners(box_a);
+ NDBOX *b = swap_corners(box_b);
+
+ if (a->dim >= b->dim)
+ {
+ result = palloc(a->size);
+ result->size = a->size;
+ result->dim = a->dim;
+ }
+ else
+ {
+ result = palloc(b->size);
+ result->size = b->size;
+ result->dim = b->dim;
+ }
+
+ /* swap the box pointers if needed */
+ if (a->dim < b->dim)
+ {
+ NDBOX *tmp = b;
+
+ b = a;
+ a = tmp;
+ }
+
+ /*
+ * use the potentially smaller of the two boxes (b) to fill in the
+ * result, padding absent dimensions with zeroes
+ */
+ for (i = 0; i < b->dim; i++)
+ {
+ result->x[i] = b->x[i];
+ result->x[i + a->dim] = b->x[i + b->dim];
+ }
+ for (i = b->dim; i < a->dim; i++)
+ {
+ result->x[i] = 0;
+ result->x[i + a->dim] = 0;
+ }
+
+ /* compute the intersection */
+ for (i = 0; i < a->dim; i++)
+ result->x[i] = max(a->x[i], result->x[i]);
+ for (i = a->dim; i < a->dim * 2; i++)
+ result->x[i] = min(a->x[i], result->x[i]);
+
+ pfree(a);
+ pfree(b);
+
+ /*
+ * Is it OK to return a non-null intersection for non-overlapping
+ * boxes?
+ */
+ return (result);
}
/* cube_size */
-float *cube_size(NDBOX *a)
+float *
+cube_size(NDBOX * a)
{
- int i,j;
- float *result;
-
- result = (float *) palloc(sizeof(float));
-
- *result = 1.0;
- for ( i = 0, j = a->dim; i < a->dim; i++,j++ ) {
- *result=(*result)*abs((a->x[j] - a->x[i]));
- }
-
- return(result);
+ int i,
+ j;
+ float *result;
+
+ result = (float *) palloc(sizeof(float));
+
+ *result = 1.0;
+ for (i = 0, j = a->dim; i < a->dim; i++, j++)
+ *result = (*result) * abs((a->x[j] - a->x[i]));
+
+ return (result);
}
void
-rt_cube_size(NDBOX *a, float *size)
+rt_cube_size(NDBOX * a, float *size)
{
- int i,j;
- if (a == (NDBOX *) NULL)
- *size = 0.0;
- else {
- *size = 1.0;
- for ( i = 0, j = a->dim; i < a->dim; i++,j++ ) {
- *size=(*size)*abs((a->x[j] - a->x[i]));
- }
- }
- return;
+ int i,
+ j;
+
+ if (a == (NDBOX *) NULL)
+ *size = 0.0;
+ else
+ {
+ *size = 1.0;
+ for (i = 0, j = a->dim; i < a->dim; i++, j++)
+ *size = (*size) * abs((a->x[j] - a->x[i]));
+ }
+ return;
}
/* The following four methods compare the projections of the boxes
@@ -631,428 +692,489 @@ rt_cube_size(NDBOX *a, float *size)
larger than 2, but it seems that R-tree requires all its strategies
map to real functions that return something */
-/* is the right edge of (a) located to the left of
- the right edge of (b)? */
-bool cube_over_left(NDBOX *box_a, NDBOX *box_b)
+/* is the right edge of (a) located to the left of
+ the right edge of (b)? */
+bool
+cube_over_left(NDBOX * box_a, NDBOX * box_b)
{
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
- return( a->x[a->dim - 1] <= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b) );
+ return (a->x[a->dim - 1] <= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b));
}
-/* is the left edge of (a) located to the right of
- the left edge of (b)? */
-bool cube_over_right(NDBOX *box_a, NDBOX *box_b)
+/* is the left edge of (a) located to the right of
+ the left edge of (b)? */
+bool
+cube_over_right(NDBOX * box_a, NDBOX * box_b)
{
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
+ NDBOX *a;
+ NDBOX *b;
- a = swap_corners(box_a);
- b = swap_corners(box_b);
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
- return( a->x[a->dim - 1] >= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b) );
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+
+ return (a->x[a->dim - 1] >= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b));
}
/* return 'true' if the projection of 'a' is
entirely on the left of the projection of 'b' */
-bool cube_left(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_left(NDBOX * box_a, NDBOX * box_b)
{
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
- return( a->x[a->dim - 1] < b->x[0]);
+ return (a->x[a->dim - 1] < b->x[0]);
}
/* return 'true' if the projection of 'a' is
entirely on the right of the projection of 'b' */
-bool cube_right(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_right(NDBOX * box_a, NDBOX * box_b)
{
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
+ NDBOX *a;
+ NDBOX *b;
- a = swap_corners(box_a);
- b = swap_corners(box_b);
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
- return( a->x[0] > b->x[b->dim - 1]);
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+
+ return (a->x[0] > b->x[b->dim - 1]);
}
/* make up a metric in which one box will be 'lower' than the other
-- this can be useful for srting and to determine uniqueness */
-bool cube_lt(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_lt(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- int dim;
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
-
- a = swap_corners(box_a);
- b = swap_corners(box_b);
- dim = min(a->dim, b->dim);
-
- /* if all common dimensions are equal, the cube with more dimensions wins */
- if ( cube_same(a, b) ) {
- if (a->dim < b->dim) {
- return(TRUE);
- }
- else {
- return(FALSE);
- }
- }
-
- /* compare the common dimensions */
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i] > b->x[i] )
- return(FALSE);
- if ( a->x[i] < b->x[i] )
- return(TRUE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i + a->dim] > b->x[i + b->dim] )
- return(FALSE);
- if ( a->x[i + a->dim] < b->x[i + b->dim] )
- return(TRUE);
- }
-
- /* compare extra dimensions to zero */
- if ( a->dim > b->dim ) {
- for ( i = dim; i < a->dim; i++ ) {
- if ( a->x[i] > 0 )
- return(FALSE);
- if ( a->x[i] < 0 )
- return(TRUE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i + a->dim] > 0 )
- return(FALSE);
- if ( a->x[i + a->dim] < 0 )
- return(TRUE);
- }
- }
- if ( a->dim < b->dim ) {
- for ( i = dim; i < b->dim; i++ ) {
- if ( b->x[i] > 0 )
- return(TRUE);
- if ( b->x[i] < 0 )
- return(FALSE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( b->x[i + b->dim] > 0 )
- return(TRUE);
- if ( b->x[i + b->dim] < 0 )
- return(FALSE);
- }
- }
-
- return(FALSE);
+ int i;
+ int dim;
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
+
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+ dim = min(a->dim, b->dim);
+
+ /*
+ * if all common dimensions are equal, the cube with more dimensions
+ * wins
+ */
+ if (cube_same(a, b))
+ {
+ if (a->dim < b->dim)
+ return (TRUE);
+ else
+ return (FALSE);
+ }
+
+ /* compare the common dimensions */
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i] > b->x[i])
+ return (FALSE);
+ if (a->x[i] < b->x[i])
+ return (TRUE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i + a->dim] > b->x[i + b->dim])
+ return (FALSE);
+ if (a->x[i + a->dim] < b->x[i + b->dim])
+ return (TRUE);
+ }
+
+ /* compare extra dimensions to zero */
+ if (a->dim > b->dim)
+ {
+ for (i = dim; i < a->dim; i++)
+ {
+ if (a->x[i] > 0)
+ return (FALSE);
+ if (a->x[i] < 0)
+ return (TRUE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i + a->dim] > 0)
+ return (FALSE);
+ if (a->x[i + a->dim] < 0)
+ return (TRUE);
+ }
+ }
+ if (a->dim < b->dim)
+ {
+ for (i = dim; i < b->dim; i++)
+ {
+ if (b->x[i] > 0)
+ return (TRUE);
+ if (b->x[i] < 0)
+ return (FALSE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (b->x[i + b->dim] > 0)
+ return (TRUE);
+ if (b->x[i + b->dim] < 0)
+ return (FALSE);
+ }
+ }
+
+ return (FALSE);
}
-bool cube_gt(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_gt(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- int dim;
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
-
- a = swap_corners(box_a);
- b = swap_corners(box_b);
- dim = min(a->dim, b->dim);
-
- /* if all common dimensions are equal, the cube with more dimensions wins */
- if ( cube_same(a, b) ) {
- if (a->dim > b->dim) {
- return(TRUE);
- }
- else {
- return(FALSE);
- }
- }
-
- /* compare the common dimensions */
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i] < b->x[i] )
- return(FALSE);
- if ( a->x[i] > b->x[i] )
- return(TRUE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i + a->dim] < b->x[i + b->dim] )
- return(FALSE);
- if ( a->x[i + a->dim] > b->x[i + b->dim] )
- return(TRUE);
- }
-
-
- /* compare extra dimensions to zero */
- if ( a->dim > b->dim ) {
- for ( i = dim; i < a->dim; i++ ) {
- if ( a->x[i] < 0 )
- return(FALSE);
- if ( a->x[i] > 0 )
- return(TRUE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( a->x[i + a->dim] < 0 )
- return(FALSE);
- if ( a->x[i + a->dim] > 0 )
- return(TRUE);
- }
- }
- if ( a->dim < b->dim ) {
- for ( i = dim; i < b->dim; i++ ) {
- if ( b->x[i] < 0 )
- return(TRUE);
- if ( b->x[i] > 0 )
- return(FALSE);
- }
- for ( i = 0; i < dim; i++ ) {
- if ( b->x[i + b->dim] < 0 )
- return(TRUE);
- if ( b->x[i + b->dim] > 0 )
- return(FALSE);
- }
- }
-
- return(FALSE);
+ int i;
+ int dim;
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
+
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+ dim = min(a->dim, b->dim);
+
+ /*
+ * if all common dimensions are equal, the cube with more dimensions
+ * wins
+ */
+ if (cube_same(a, b))
+ {
+ if (a->dim > b->dim)
+ return (TRUE);
+ else
+ return (FALSE);
+ }
+
+ /* compare the common dimensions */
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i] < b->x[i])
+ return (FALSE);
+ if (a->x[i] > b->x[i])
+ return (TRUE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i + a->dim] < b->x[i + b->dim])
+ return (FALSE);
+ if (a->x[i + a->dim] > b->x[i + b->dim])
+ return (TRUE);
+ }
+
+
+ /* compare extra dimensions to zero */
+ if (a->dim > b->dim)
+ {
+ for (i = dim; i < a->dim; i++)
+ {
+ if (a->x[i] < 0)
+ return (FALSE);
+ if (a->x[i] > 0)
+ return (TRUE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (a->x[i + a->dim] < 0)
+ return (FALSE);
+ if (a->x[i + a->dim] > 0)
+ return (TRUE);
+ }
+ }
+ if (a->dim < b->dim)
+ {
+ for (i = dim; i < b->dim; i++)
+ {
+ if (b->x[i] < 0)
+ return (TRUE);
+ if (b->x[i] > 0)
+ return (FALSE);
+ }
+ for (i = 0; i < dim; i++)
+ {
+ if (b->x[i + b->dim] < 0)
+ return (TRUE);
+ if (b->x[i + b->dim] > 0)
+ return (FALSE);
+ }
+ }
+
+ return (FALSE);
}
/* Equal */
-bool cube_same(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_same(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
-
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
- /* swap the box pointers if necessary */
- if ( a->dim < b->dim ) {
- NDBOX * tmp = b; b = a; a = tmp;
- }
-
- for ( i = 0; i < b->dim; i++ ) {
- if ( a->x[i] != b->x[i] )
- return(FALSE);
- if ( a->x[i + a->dim] != b->x[i + b->dim] )
- return(FALSE);
- }
-
- /* all dimensions of (b) are compared to those of (a);
- instead of those in (a) absent in (b), compare (a) to zero */
- for ( i = b->dim; i < a->dim; i++ ) {
- if ( a->x[i] != 0 )
- return(FALSE);
- if ( a->x[i + a->dim] != 0 )
- return(FALSE);
- }
-
- pfree(a);
- pfree(b);
-
- return(TRUE);
+ int i;
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
+
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+
+ /* swap the box pointers if necessary */
+ if (a->dim < b->dim)
+ {
+ NDBOX *tmp = b;
+
+ b = a;
+ a = tmp;
+ }
+
+ for (i = 0; i < b->dim; i++)
+ {
+ if (a->x[i] != b->x[i])
+ return (FALSE);
+ if (a->x[i + a->dim] != b->x[i + b->dim])
+ return (FALSE);
+ }
+
+ /*
+ * all dimensions of (b) are compared to those of (a); instead of
+ * those in (a) absent in (b), compare (a) to zero
+ */
+ for (i = b->dim; i < a->dim; i++)
+ {
+ if (a->x[i] != 0)
+ return (FALSE);
+ if (a->x[i + a->dim] != 0)
+ return (FALSE);
+ }
+
+ pfree(a);
+ pfree(b);
+
+ return (TRUE);
}
/* Different */
-bool cube_different(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_different(NDBOX * box_a, NDBOX * box_b)
{
- return(!cube_same(box_a, box_b));
+ return (!cube_same(box_a, box_b));
}
/* Contains */
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
-bool cube_contains(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_contains(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- NDBOX *a;
- NDBOX *b;
-
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
-
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
- if ( a->dim < b->dim ) {
- /* the further comparisons will make sense if the
- excess dimensions of (b) were zeroes */
- for ( i = a->dim; i < b->dim; i++ ) {
- if ( b->x[i] != 0 )
- return(FALSE);
- if ( b->x[i + b->dim] != 0 )
- return(FALSE);
- }
- }
-
- /* Can't care less about the excess dimensions of (a), if any */
- for ( i = 0; i < min(a->dim, b->dim); i++ ) {
- if ( a->x[i] > b->x[i] )
- return(FALSE);
- if ( a->x[i + a->dim] < b->x[i + b->dim] )
- return(FALSE);
- }
-
- pfree(a);
- pfree(b);
-
- return(TRUE);
+ int i;
+ NDBOX *a;
+ NDBOX *b;
+
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
+
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+
+ if (a->dim < b->dim)
+ {
+
+ /*
+ * the further comparisons will make sense if the excess
+ * dimensions of (b) were zeroes
+ */
+ for (i = a->dim; i < b->dim; i++)
+ {
+ if (b->x[i] != 0)
+ return (FALSE);
+ if (b->x[i + b->dim] != 0)
+ return (FALSE);
+ }
+ }
+
+ /* Can't care less about the excess dimensions of (a), if any */
+ for (i = 0; i < min(a->dim, b->dim); i++)
+ {
+ if (a->x[i] > b->x[i])
+ return (FALSE);
+ if (a->x[i + a->dim] < b->x[i + b->dim])
+ return (FALSE);
+ }
+
+ pfree(a);
+ pfree(b);
+
+ return (TRUE);
}
/* Contained */
/* Box(A) Contained by Box(B) IFF Box(B) Contains Box(A) */
-bool cube_contained (NDBOX *a, NDBOX *b)
+bool
+cube_contained(NDBOX * a, NDBOX * b)
{
- if (cube_contains(b,a) == TRUE)
- return(TRUE);
- else
- return(FALSE);
+ if (cube_contains(b, a) == TRUE)
+ return (TRUE);
+ else
+ return (FALSE);
}
/* Overlap */
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
-bool cube_overlap(NDBOX *box_a, NDBOX *box_b)
+bool
+cube_overlap(NDBOX * box_a, NDBOX * box_b)
{
- int i;
- NDBOX *a;
- NDBOX *b;
-
- /* This *very bad* error was found in the source:
- if ( (a==NULL) || (b=NULL) )
- return(FALSE);
- */
- if ( (box_a==NULL) || (box_b==NULL) )
- return(FALSE);
-
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
- /* swap the box pointers if needed */
- if ( a->dim < b->dim ) {
- NDBOX * tmp = b; b = a; a = tmp;
- }
-
- /* compare within the dimensions of (b) */
- for ( i = 0; i < b->dim; i++ ) {
- if ( a->x[i] > b->x[i + b->dim] )
- return(FALSE);
- if ( a->x[i + a->dim] < b->x[i] )
- return(FALSE);
- }
-
- /* compare to zero those dimensions in (a) absent in (b) */
- for ( i = b->dim; i < a->dim; i++ ) {
- if ( a->x[i] > 0 )
- return(FALSE);
- if ( a->x[i + a->dim] < 0 )
- return(FALSE);
- }
-
- pfree(a);
- pfree(b);
-
- return(TRUE);
+ int i;
+ NDBOX *a;
+ NDBOX *b;
+
+ /*
+ * This *very bad* error was found in the source: if ( (a==NULL) ||
+ * (b=NULL) ) return(FALSE);
+ */
+ if ((box_a == NULL) || (box_b == NULL))
+ return (FALSE);
+
+ a = swap_corners(box_a);
+ b = swap_corners(box_b);
+
+ /* swap the box pointers if needed */
+ if (a->dim < b->dim)
+ {
+ NDBOX *tmp = b;
+
+ b = a;
+ a = tmp;
+ }
+
+ /* compare within the dimensions of (b) */
+ for (i = 0; i < b->dim; i++)
+ {
+ if (a->x[i] > b->x[i + b->dim])
+ return (FALSE);
+ if (a->x[i + a->dim] < b->x[i])
+ return (FALSE);
+ }
+
+ /* compare to zero those dimensions in (a) absent in (b) */
+ for (i = b->dim; i < a->dim; i++)
+ {
+ if (a->x[i] > 0)
+ return (FALSE);
+ if (a->x[i + a->dim] < 0)
+ return (FALSE);
+ }
+
+ pfree(a);
+ pfree(b);
+
+ return (TRUE);
}
/* Distance */
/* The distance is computed as a per axis sum of the squared distances
- between 1D projections of the boxes onto Cartesian axes. Assuming zero
- distance between overlapping projections, this metric coincides with the
+ between 1D projections of the boxes onto Cartesian axes. Assuming zero
+ distance between overlapping projections, this metric coincides with the
"common sense" geometric distance */
-float *cube_distance(NDBOX *a, NDBOX *b)
+float *
+cube_distance(NDBOX * a, NDBOX * b)
{
- int i;
- double d, distance;
- float *result;
-
- result = (float *) palloc(sizeof(float));
-
- /* swap the box pointers if needed */
- if ( a->dim < b->dim ) {
- NDBOX * tmp = b; b = a; a = tmp;
- }
-
- distance = 0.0;
- /* compute within the dimensions of (b) */
- for ( i = 0; i < b->dim; i++ ) {
- d = distance_1D(a->x[i], a->x[i + a->dim], b->x[i], b->x[i + b->dim]);
- distance += d*d;
- }
-
- /* compute distance to zero for those dimensions in (a) absent in (b) */
- for ( i = b->dim; i < a->dim; i++ ) {
- d = distance_1D(a->x[i], a->x[i + a->dim], 0.0, 0.0);
- distance += d*d;
- }
-
- *result = (float)sqrt(distance);
-
- return(result);
+ int i;
+ double d,
+ distance;
+ float *result;
+
+ result = (float *) palloc(sizeof(float));
+
+ /* swap the box pointers if needed */
+ if (a->dim < b->dim)
+ {
+ NDBOX *tmp = b;
+
+ b = a;
+ a = tmp;
+ }
+
+ distance = 0.0;
+ /* compute within the dimensions of (b) */
+ for (i = 0; i < b->dim; i++)
+ {
+ d = distance_1D(a->x[i], a->x[i + a->dim], b->x[i], b->x[i + b->dim]);
+ distance += d * d;
+ }
+
+ /* compute distance to zero for those dimensions in (a) absent in (b) */
+ for (i = b->dim; i < a->dim; i++)
+ {
+ d = distance_1D(a->x[i], a->x[i + a->dim], 0.0, 0.0);
+ distance += d * d;
+ }
+
+ *result = (float) sqrt(distance);
+
+ return (result);
}
-static float distance_1D(float a1, float a2, float b1, float b2)
+static float
+distance_1D(float a1, float a2, float b1, float b2)
{
- /* interval (a) is entirely on the left of (b) */
- if( (a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2) ) {
- return ( min( b1, b2 ) - max( a1, a2 ) );
- }
-
- /* interval (a) is entirely on the right of (b) */
- if( (a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2) ) {
- return ( min( a1, a2 ) - max( b1, b2 ) );
- }
-
- /* the rest are all sorts of intersections */
- return(0.0);
+ /* interval (a) is entirely on the left of (b) */
+ if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
+ return (min(b1, b2) - max(a1, a2));
+
+ /* interval (a) is entirely on the right of (b) */
+ if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2))
+ return (min(a1, a2) - max(b1, b2));
+
+ /* the rest are all sorts of intersections */
+ return (0.0);
}
/* normalize the box's co-ordinates by placing min(xLL,xUR) to LL
- and max(xLL,xUR) to UR
+ and max(xLL,xUR) to UR
*/
-static NDBOX *swap_corners ( NDBOX *a )
+static NDBOX *
+swap_corners(NDBOX * a)
{
- int i, j;
- NDBOX * result;
-
- result = palloc(a->size);
- result->size = a->size;
- result->dim = a->dim;
-
- for ( i = 0, j = a->dim; i < a->dim; i++, j++ ) {
- result->x[i] = min(a->x[i],a->x[j]);
- result->x[j] = max(a->x[i],a->x[j]);
- }
-
- return(result);
+ int i,
+ j;
+ NDBOX *result;
+
+ result = palloc(a->size);
+ result->size = a->size;
+ result->dim = a->dim;
+
+ for (i = 0, j = a->dim; i < a->dim; i++, j++)
+ {
+ result->x[i] = min(a->x[i], a->x[j]);
+ result->x[j] = max(a->x[i], a->x[j]);
+ }
+
+ return (result);
}