aboutsummaryrefslogtreecommitdiff
path: root/contrib/seg/seg.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/seg/seg.c')
-rw-r--r--contrib/seg/seg.c1391
1 files changed, 737 insertions, 654 deletions
diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c
index 1609b42b1ea..3ed79263891 100644
--- a/contrib/seg/seg.c
+++ b/contrib/seg/seg.c
@@ -16,79 +16,80 @@
#include "segdata.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))
-/*
+/*
#define GIST_DEBUG
-#define GIST_QUERY_DEBUG
+#define GIST_QUERY_DEBUG
*/
-extern void set_parse_buffer(char *str);
-extern int seg_yyparse();
+extern void set_parse_buffer(char *str);
+extern int seg_yyparse();
+
/*
-extern int seg_yydebug;
+extern int seg_yydebug;
*/
/*
** Input/Output routines
*/
-SEG * seg_in(char *str);
-char * seg_out(SEG *seg);
-float32 seg_lower(SEG *seg);
-float32 seg_upper(SEG *seg);
-float32 seg_center(SEG *seg);
+SEG *seg_in(char *str);
+char *seg_out(SEG * seg);
+float32 seg_lower(SEG * seg);
+float32 seg_upper(SEG * seg);
+float32 seg_center(SEG * seg);
-/*
+/*
** GiST support methods
*/
-bool gseg_consistent(GISTENTRY *entry, SEG *query, StrategyNumber strategy);
-GISTENTRY * gseg_compress(GISTENTRY *entry);
-GISTENTRY * gseg_decompress(GISTENTRY *entry);
-float * gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
-GIST_SPLITVEC * gseg_picksplit(bytea *entryvec, GIST_SPLITVEC *v);
-bool gseg_leaf_consistent(SEG *key, SEG *query, StrategyNumber strategy);
-bool gseg_internal_consistent(SEG *key, SEG *query, StrategyNumber strategy);
-SEG * gseg_union(bytea *entryvec, int *sizep);
-SEG * gseg_binary_union(SEG *r1, SEG *r2, int *sizep);
-bool * gseg_same(SEG *b1, SEG *b2, bool *result);
+bool gseg_consistent(GISTENTRY *entry, SEG * query, StrategyNumber strategy);
+GISTENTRY *gseg_compress(GISTENTRY *entry);
+GISTENTRY *gseg_decompress(GISTENTRY *entry);
+float *gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
+GIST_SPLITVEC *gseg_picksplit(bytea *entryvec, GIST_SPLITVEC *v);
+bool gseg_leaf_consistent(SEG * key, SEG * query, StrategyNumber strategy);
+bool gseg_internal_consistent(SEG * key, SEG * query, StrategyNumber strategy);
+SEG *gseg_union(bytea *entryvec, int *sizep);
+SEG *gseg_binary_union(SEG * r1, SEG * r2, int *sizep);
+bool *gseg_same(SEG * b1, SEG * b2, bool *result);
/*
** R-tree suport functions
*/
-bool seg_same(SEG *a, SEG *b);
-bool seg_contains_int(SEG *a, int *b);
-bool seg_contains_float4(SEG *a, float4 *b);
-bool seg_contains_float8(SEG *a, float8 *b);
-bool seg_contains(SEG *a, SEG *b);
-bool seg_contained(SEG *a, SEG *b);
-bool seg_overlap(SEG *a, SEG *b);
-bool seg_left(SEG *a, SEG *b);
-bool seg_over_left(SEG *a, SEG *b);
-bool seg_right(SEG *a, SEG *b);
-bool seg_over_right(SEG *a, SEG *b);
-SEG * seg_union(SEG *a, SEG *b);
-SEG * seg_inter(SEG *a, SEG *b);
-void rt_seg_size(SEG *a, float* sz);
-float * seg_size(SEG *a);
+bool seg_same(SEG * a, SEG * b);
+bool seg_contains_int(SEG * a, int *b);
+bool seg_contains_float4(SEG * a, float4 *b);
+bool seg_contains_float8(SEG * a, float8 *b);
+bool seg_contains(SEG * a, SEG * b);
+bool seg_contained(SEG * a, SEG * b);
+bool seg_overlap(SEG * a, SEG * b);
+bool seg_left(SEG * a, SEG * b);
+bool seg_over_left(SEG * a, SEG * b);
+bool seg_right(SEG * a, SEG * b);
+bool seg_over_right(SEG * a, SEG * b);
+SEG *seg_union(SEG * a, SEG * b);
+SEG *seg_inter(SEG * a, SEG * b);
+void rt_seg_size(SEG * a, float *sz);
+float *seg_size(SEG * a);
/*
** Various operators
*/
-int32 seg_cmp(SEG *a, SEG *b);
-bool seg_lt(SEG *a, SEG *b);
-bool seg_le(SEG *a, SEG *b);
-bool seg_gt(SEG *a, SEG *b);
-bool seg_ge(SEG *a, SEG *b);
-bool seg_different(SEG *a, SEG *b);
-
-/*
+int32 seg_cmp(SEG * a, SEG * b);
+bool seg_lt(SEG * a, SEG * b);
+bool seg_le(SEG * a, SEG * b);
+bool seg_gt(SEG * a, SEG * b);
+bool seg_ge(SEG * a, SEG * b);
+bool seg_different(SEG * a, SEG * b);
+
+/*
** Auxiliary funxtions
*/
-static int restore(char *s, float val, int n);
-int significant_digits (char* s);
+static int restore(char *s, float val, int n);
+int significant_digits(char *s);
/*****************************************************************************
@@ -98,104 +99,113 @@ int significant_digits (char* s);
SEG *
seg_in(char *str)
{
- SEG * result = palloc(sizeof(SEG));
- set_parse_buffer( str );
-
- /*
- seg_yydebug = 1;
- */
- if ( seg_yyparse(result) != 0 ) {
- pfree ( result );
- return NULL;
- }
- return ( result );
+ SEG *result = palloc(sizeof(SEG));
+
+ set_parse_buffer(str);
+
+ /*
+ * seg_yydebug = 1;
+ */
+ if (seg_yyparse(result) != 0)
+ {
+ pfree(result);
+ return NULL;
+ }
+ return (result);
}
/*
* You might have noticed a slight inconsistency between the following
* declaration and the SQL definition:
- * CREATE FUNCTION seg_out(opaque) RETURNS opaque ...
+ * CREATE FUNCTION seg_out(opaque) RETURNS opaque ...
* The reason is that the argument passed into seg_out is really just a
* pointer. POSTGRES thinks all output functions are:
- * char *out_func(char *);
+ * char *out_func(char *);
*/
char *
-seg_out(SEG *seg)
+seg_out(SEG * seg)
{
- char *result;
- char *p;
-
- if (seg == NULL) return(NULL);
-
- p = result = (char *) palloc(40);
-
- if ( seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~' ) {
- p += sprintf(p, "%c", seg->l_ext);
- }
-
- if ( seg->lower == seg->upper && seg->l_ext == seg->u_ext ) {
- /* indicates that this interval was built by seg_in off a single point */
- p += restore(p, seg->lower, seg->l_sigd);
- }
- else {
- if ( seg->l_ext != '-' ) {
- /* print the lower boudary if exists */
- p += restore(p, seg->lower, seg->l_sigd);
- p += sprintf(p, " ");
- }
- p += sprintf(p, "..");
- if ( seg->u_ext != '-' ) {
- /* print the upper boudary if exists */
- p += sprintf(p, " ");
- if ( seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~' ) {
- p += sprintf(p, "%c", seg->u_ext);
+ char *result;
+ char *p;
+
+ if (seg == NULL)
+ return (NULL);
+
+ p = result = (char *) palloc(40);
+
+ if (seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~')
+ p += sprintf(p, "%c", seg->l_ext);
+
+ if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
+ {
+
+ /*
+ * indicates that this interval was built by seg_in off a single
+ * point
+ */
+ p += restore(p, seg->lower, seg->l_sigd);
+ }
+ else
+ {
+ if (seg->l_ext != '-')
+ {
+ /* print the lower boudary if exists */
+ p += restore(p, seg->lower, seg->l_sigd);
+ p += sprintf(p, " ");
+ }
+ p += sprintf(p, "..");
+ if (seg->u_ext != '-')
+ {
+ /* print the upper boudary if exists */
+ p += sprintf(p, " ");
+ if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~')
+ p += sprintf(p, "%c", seg->u_ext);
+ p += restore(p, seg->upper, seg->u_sigd);
+ }
}
- p += restore(p, seg->upper, seg->u_sigd);
- }
- }
- return(result);
+ return (result);
}
float32
-seg_center(SEG *seg)
+seg_center(SEG * seg)
{
- float32 result = (float32) palloc(sizeof(float32data));
+ float32 result = (float32) palloc(sizeof(float32data));
- if (!seg)
- return (float32) NULL;
+ if (!seg)
+ return (float32) NULL;
- *result = ((float)seg->lower + (float)seg->upper)/2.0;
- return (result);
+ *result = ((float) seg->lower + (float) seg->upper) / 2.0;
+ return (result);
}
float32
-seg_lower(SEG *seg)
+seg_lower(SEG * seg)
{
- float32 result = (float32) palloc(sizeof(float32data));
+ float32 result = (float32) palloc(sizeof(float32data));
- if (!seg)
- return (float32) NULL;
+ if (!seg)
+ return (float32) NULL;
- *result = (float)seg->lower;
- return (result);
+ *result = (float) seg->lower;
+ return (result);
}
float32
-seg_upper(SEG *seg)
+seg_upper(SEG * seg)
{
- float32 result = (float32) palloc(sizeof(float32data));
+ float32 result = (float32) palloc(sizeof(float32data));
- if (!seg)
- return (float32) NULL;
+ if (!seg)
+ return (float32) NULL;
- *result = (float)seg->upper;
- return (result);
+ *result = (float) seg->upper;
+ return (result);
}
/*****************************************************************************
- * GiST functions
+ * GiST functions
*****************************************************************************/
/*
@@ -204,19 +214,20 @@ seg_upper(SEG *seg)
** the predicate x op query == FALSE, where op is the oper
** corresponding to strategy in the pg_amop table.
*/
-bool
+bool
gseg_consistent(GISTENTRY *entry,
- SEG *query,
- StrategyNumber strategy)
+ SEG * query,
+ StrategyNumber strategy)
{
- /*
- ** if entry is not leaf, use gseg_internal_consistent,
- ** else use gseg_leaf_consistent
- */
- if (GIST_LEAF(entry))
- return(gseg_leaf_consistent((SEG *)(entry->pred), query, strategy));
- else
- return(gseg_internal_consistent((SEG *)(entry->pred), query, strategy));
+
+ /*
+ * * if entry is not leaf, use gseg_internal_consistent, * else use
+ * gseg_leaf_consistent
+ */
+ if (GIST_LEAF(entry))
+ return (gseg_leaf_consistent((SEG *) (entry->pred), query, strategy));
+ else
+ return (gseg_internal_consistent((SEG *) (entry->pred), query, strategy));
}
/*
@@ -226,49 +237,54 @@ gseg_consistent(GISTENTRY *entry,
SEG *
gseg_union(bytea *entryvec, int *sizep)
{
- int numranges, i;
- SEG *out = (SEG *)NULL;
- SEG *tmp;
+ int numranges,
+ i;
+ SEG *out = (SEG *) NULL;
+ SEG *tmp;
#ifdef GIST_DEBUG
- fprintf(stderr, "union\n");
+ fprintf(stderr, "union\n");
#endif
- numranges = (VARSIZE(entryvec) - VARHDRSZ)/sizeof(GISTENTRY);
- tmp = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[0]).pred;
- *sizep = sizeof(SEG);
+ numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
+ tmp = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[0]).pred;
+ *sizep = sizeof(SEG);
- for (i = 1; i < numranges; i++) {
- out = gseg_binary_union(tmp, (SEG *)
- (((GISTENTRY *)(VARDATA(entryvec)))[i]).pred,
- sizep);
+ for (i = 1; i < numranges; i++)
+ {
+ out = gseg_binary_union(tmp, (SEG *)
+ (((GISTENTRY *) (VARDATA(entryvec)))[i]).pred,
+ sizep);
#ifdef GIST_DEBUG
- /*
- fprintf(stderr, "\t%s ^ %s -> %s\n", seg_out(tmp), seg_out((SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[i]).pred), seg_out(out));
- */
+
+ /*
+ * fprintf(stderr, "\t%s ^ %s -> %s\n", seg_out(tmp), seg_out((SEG
+ * *)(((GISTENTRY *)(VARDATA(entryvec)))[i]).pred), seg_out(out));
+ */
#endif
- if (i > 1) pfree(tmp);
- tmp = out;
- }
+ if (i > 1)
+ pfree(tmp);
+ tmp = out;
+ }
- return(out);
+ return (out);
}
/*
** GiST Compress and Decompress methods for segments
** do not do anything.
*/
-GISTENTRY *
+GISTENTRY *
gseg_compress(GISTENTRY *entry)
{
- return(entry);
+ return (entry);
}
-GISTENTRY *
+GISTENTRY *
gseg_decompress(GISTENTRY *entry)
{
- return(entry);
+ return (entry);
}
/*
@@ -278,287 +294,312 @@ gseg_decompress(GISTENTRY *entry)
float *
gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{
- Datum ud;
- float tmp1, tmp2;
-
- ud = (Datum)seg_union((SEG *)(origentry->pred), (SEG *)(newentry->pred));
- rt_seg_size((SEG *)ud, &tmp1);
- rt_seg_size((SEG *)(origentry->pred), &tmp2);
- *result = tmp1 - tmp2;
- pfree((char *)ud);
+ Datum ud;
+ float tmp1,
+ tmp2;
+
+ ud = (Datum) seg_union((SEG *) (origentry->pred), (SEG *) (newentry->pred));
+ rt_seg_size((SEG *) ud, &tmp1);
+ rt_seg_size((SEG *) (origentry->pred), &tmp2);
+ *result = tmp1 - tmp2;
+ pfree((char *) ud);
#ifdef GIST_DEBUG
- fprintf(stderr, "penalty\n");
- fprintf(stderr, "\t%g\n", *result);
+ fprintf(stderr, "penalty\n");
+ fprintf(stderr, "\t%g\n", *result);
#endif
- return(result);
+ return (result);
}
/*
** The GiST PickSplit method for segments
-** We use Guttman's poly time split algorithm
+** We use Guttman's poly time split algorithm
*/
GIST_SPLITVEC *
gseg_picksplit(bytea *entryvec,
- GIST_SPLITVEC *v)
+ GIST_SPLITVEC *v)
{
- OffsetNumber i, j;
- SEG *datum_alpha, *datum_beta;
- SEG *datum_l, *datum_r;
- SEG *union_d, *union_dl, *union_dr;
- SEG *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;
+ OffsetNumber i,
+ j;
+ SEG *datum_alpha,
+ *datum_beta;
+ SEG *datum_l,
+ *datum_r;
+ SEG *union_d,
+ *union_dl,
+ *union_dr;
+ SEG *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;
#ifdef GIST_DEBUG
- fprintf(stderr, "picksplit\n");
+ fprintf(stderr, "picksplit\n");
#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 = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[i].pred);
- for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) {
- datum_beta = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[j].pred);
-
- /* compute the wasted space by unioning these guys */
- /* size_waste = size_union - size_inter; */
- union_d = (SEG *)seg_union(datum_alpha, datum_beta);
- rt_seg_size(union_d, &size_union);
- inter_d = (SEG *)seg_inter(datum_alpha, datum_beta);
- rt_seg_size(inter_d, &size_inter);
- size_waste = size_union - size_inter;
-
- pfree(union_d);
-
- if (inter_d != (SEG *) 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;
- }
+ 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 = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred);
+ for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
+ {
+ datum_beta = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[j].pred);
+
+ /* compute the wasted space by unioning these guys */
+ /* size_waste = size_union - size_inter; */
+ union_d = (SEG *) seg_union(datum_alpha, datum_beta);
+ rt_seg_size(union_d, &size_union);
+ inter_d = (SEG *) seg_inter(datum_alpha, datum_beta);
+ rt_seg_size(inter_d, &size_inter);
+ size_waste = size_union - size_inter;
+
+ pfree(union_d);
+
+ if (inter_d != (SEG *) 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;
-
- datum_alpha = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[seed_1].pred);
- datum_l = (SEG *)seg_union(datum_alpha, datum_alpha);
- rt_seg_size((SEG *)datum_l, &size_l);
- datum_beta = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[seed_2].pred);;
- datum_r = (SEG *)seg_union(datum_beta, datum_beta);
- rt_seg_size((SEG *)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)) {
-
+
+ left = v->spl_left;
+ v->spl_nleft = 0;
+ right = v->spl_right;
+ v->spl_nright = 0;
+
+ datum_alpha = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_1].pred);
+ datum_l = (SEG *) seg_union(datum_alpha, datum_alpha);
+ rt_seg_size((SEG *) datum_l, &size_l);
+ datum_beta = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[seed_2].pred);;
+ datum_r = (SEG *) seg_union(datum_beta, datum_beta);
+ rt_seg_size((SEG *) datum_r, &size_r);
+
/*
- * 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.
+ * 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.
*/
-
- 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 = (SEG *)(((GISTENTRY *)(VARDATA(entryvec)))[i].pred);
- union_dl = (SEG *)seg_union(datum_l, datum_alpha);
- union_dr = (SEG *)seg_union(datum_r, datum_alpha);
- rt_seg_size((SEG *)union_dl, &size_alpha);
- rt_seg_size((SEG *)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++;
+
+ 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 = (SEG *) (((GISTENTRY *) (VARDATA(entryvec)))[i].pred);
+ union_dl = (SEG *) seg_union(datum_l, datum_alpha);
+ union_dr = (SEG *) seg_union(datum_r, datum_alpha);
+ rt_seg_size((SEG *) union_dl, &size_alpha);
+ rt_seg_size((SEG *) 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() */
+
+ v->spl_ldatum = (char *) datum_l;
+ v->spl_rdatum = (char *) datum_r;
- return v;
+ return v;
}
/*
** Equality methods
*/
bool *
-gseg_same(SEG *b1, SEG *b2, bool *result)
+gseg_same(SEG * b1, SEG * b2, bool *result)
{
- if (seg_same(b1, b2))
- *result = TRUE;
- else *result = FALSE;
+ if (seg_same(b1, b2))
+ *result = TRUE;
+ else
+ *result = FALSE;
#ifdef GIST_DEBUG
- fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
+ fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
#endif
- return(result);
+ return (result);
}
-/*
+/*
** SUPPORT ROUTINES
*/
-bool
-gseg_leaf_consistent(SEG *key,
- SEG *query,
- StrategyNumber strategy)
+bool
+gseg_leaf_consistent(SEG * key,
+ SEG * query,
+ StrategyNumber strategy)
{
- bool retval;
+ bool retval;
#ifdef GIST_QUERY_DEBUG
- fprintf(stderr, "leaf_consistent, %d\n", strategy);
+ fprintf(stderr, "leaf_consistent, %d\n", strategy);
#endif
- switch(strategy) {
- case RTLeftStrategyNumber:
- retval = (bool)seg_left(key, query);
- break;
- case RTOverLeftStrategyNumber:
- retval = (bool)seg_over_left(key,query);
- break;
- case RTOverlapStrategyNumber:
- retval = (bool)seg_overlap(key, query);
- break;
- case RTOverRightStrategyNumber:
- retval = (bool)seg_over_right(key, query);
- break;
- case RTRightStrategyNumber:
- retval = (bool)seg_right(key, query);
- break;
- case RTSameStrategyNumber:
- retval = (bool)seg_same(key, query);
- break;
- case RTContainsStrategyNumber:
- retval = (bool)seg_contains(key, query);
- break;
- case RTContainedByStrategyNumber:
- retval = (bool)seg_contained(key,query);
- break;
- default:
- retval = FALSE;
- }
- return(retval);
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ retval = (bool) seg_left(key, query);
+ break;
+ case RTOverLeftStrategyNumber:
+ retval = (bool) seg_over_left(key, query);
+ break;
+ case RTOverlapStrategyNumber:
+ retval = (bool) seg_overlap(key, query);
+ break;
+ case RTOverRightStrategyNumber:
+ retval = (bool) seg_over_right(key, query);
+ break;
+ case RTRightStrategyNumber:
+ retval = (bool) seg_right(key, query);
+ break;
+ case RTSameStrategyNumber:
+ retval = (bool) seg_same(key, query);
+ break;
+ case RTContainsStrategyNumber:
+ retval = (bool) seg_contains(key, query);
+ break;
+ case RTContainedByStrategyNumber:
+ retval = (bool) seg_contained(key, query);
+ break;
+ default:
+ retval = FALSE;
+ }
+ return (retval);
}
-bool
-gseg_internal_consistent(SEG *key,
- SEG *query,
- StrategyNumber strategy)
+bool
+gseg_internal_consistent(SEG * key,
+ SEG * query,
+ StrategyNumber strategy)
{
- bool retval;
+ bool retval;
#ifdef GIST_QUERY_DEBUG
- fprintf(stderr, "internal_consistent, %d\n", strategy);
+ fprintf(stderr, "internal_consistent, %d\n", strategy);
#endif
- switch(strategy) {
- case RTLeftStrategyNumber:
- case RTOverLeftStrategyNumber:
- retval = (bool)seg_over_left(key,query);
- break;
- case RTOverlapStrategyNumber:
- retval = (bool)seg_overlap(key, query);
- break;
- case RTOverRightStrategyNumber:
- case RTRightStrategyNumber:
- retval = (bool)seg_right(key, query);
- break;
- case RTSameStrategyNumber:
- case RTContainsStrategyNumber:
- retval = (bool)seg_contains(key, query);
- break;
- case RTContainedByStrategyNumber:
- retval = (bool)seg_overlap(key, query);
- break;
- default:
- retval = FALSE;
- }
- return(retval);
+ switch (strategy)
+ {
+ case RTLeftStrategyNumber:
+ case RTOverLeftStrategyNumber:
+ retval = (bool) seg_over_left(key, query);
+ break;
+ case RTOverlapStrategyNumber:
+ retval = (bool) seg_overlap(key, query);
+ break;
+ case RTOverRightStrategyNumber:
+ case RTRightStrategyNumber:
+ retval = (bool) seg_right(key, query);
+ break;
+ case RTSameStrategyNumber:
+ case RTContainsStrategyNumber:
+ retval = (bool) seg_contains(key, query);
+ break;
+ case RTContainedByStrategyNumber:
+ retval = (bool) seg_overlap(key, query);
+ break;
+ default:
+ retval = FALSE;
+ }
+ return (retval);
}
SEG *
-gseg_binary_union(SEG *r1, SEG *r2, int *sizep)
+gseg_binary_union(SEG * r1, SEG * r2, int *sizep)
{
- SEG *retval;
+ SEG *retval;
- retval = seg_union(r1, r2);
- *sizep = sizeof(SEG);
+ retval = seg_union(r1, r2);
+ *sizep = sizeof(SEG);
- return (retval);
+ return (retval);
}
bool
-seg_contains(SEG *a, SEG *b)
+seg_contains(SEG * a, SEG * b)
{
- return ( (a->lower <= b->lower) && (a->upper >= b->upper) );
+ return ((a->lower <= b->lower) && (a->upper >= b->upper));
}
bool
-seg_contained(SEG *a, SEG *b)
+seg_contained(SEG * a, SEG * b)
{
- return ( seg_contains(b, a) );
+ return (seg_contains(b, a));
}
/*****************************************************************************
@@ -566,209 +607,214 @@ seg_contained(SEG *a, SEG *b)
*****************************************************************************/
bool
-seg_same(SEG *a, SEG *b)
+seg_same(SEG * a, SEG * b)
{
- return seg_cmp(a, b) == 0;
+ return seg_cmp(a, b) == 0;
}
-/* seg_overlap -- does a overlap b?
+/* seg_overlap -- does a overlap b?
*/
bool
-seg_overlap(SEG *a, SEG *b)
+seg_overlap(SEG * a, SEG * b)
{
- return (
- ((a->upper >= b->upper) && (a->lower <= b->upper))
- ||
- ((b->upper >= a->upper) && (b->lower <= a->upper))
- );
+ return (
+ ((a->upper >= b->upper) && (a->lower <= b->upper))
+ ||
+ ((b->upper >= a->upper) && (b->lower <= a->upper))
+ );
}
-/* seg_overleft -- is the right edge of (a) located to the left of the right edge of (b)?
+/* seg_overleft -- is the right edge of (a) located to the left of the right edge of (b)?
*/
bool
-seg_over_left(SEG *a, SEG *b)
+seg_over_left(SEG * a, SEG * b)
{
- return ( a->upper <= b->upper && !seg_left(a, b) && !seg_right(a, b));
+ return (a->upper <= b->upper && !seg_left(a, b) && !seg_right(a, b));
}
-/* seg_left -- is (a) entirely on the left of (b)?
+/* seg_left -- is (a) entirely on the left of (b)?
*/
bool
-seg_left(SEG *a, SEG *b)
+seg_left(SEG * a, SEG * b)
{
- return ( a->upper < b->lower );
+ return (a->upper < b->lower);
}
-/* seg_right -- is (a) entirely on the right of (b)?
+/* seg_right -- is (a) entirely on the right of (b)?
*/
bool
-seg_right(SEG *a, SEG *b)
+seg_right(SEG * a, SEG * b)
{
- return ( a->lower > b->upper );
+ return (a->lower > b->upper);
}
-/* seg_overright -- is the left edge of (a) located to the right of the left edge of (b)?
+/* seg_overright -- is the left edge of (a) located to the right of the left edge of (b)?
*/
bool
-seg_over_right(SEG *a, SEG *b)
+seg_over_right(SEG * a, SEG * b)
{
- return (a->lower >= b->lower && !seg_left(a, b) && !seg_right(a, b));
+ return (a->lower >= b->lower && !seg_left(a, b) && !seg_right(a, b));
}
SEG *
-seg_union(SEG *a, SEG *b)
+seg_union(SEG * a, SEG * b)
{
- SEG *n;
-
- n = (SEG *) palloc(sizeof(*n));
-
- /* take max of upper endpoints */
- if (a->upper > b->upper)
- {
- n->upper = a->upper;
- n->u_sigd = a->u_sigd;
- n->u_ext = a->u_ext;
- }
- else
- {
- n->upper = b->upper;
- n->u_sigd = b->u_sigd;
- n->u_ext = b->u_ext;
- }
-
- /* take min of lower endpoints */
- if (a->lower < b->lower)
- {
- n->lower = a->lower;
- n->l_sigd = a->l_sigd;
- n->l_ext = a->l_ext;
- }
- else
- {
- n->lower = b->lower;
- n->l_sigd = b->l_sigd;
- n->l_ext = b->l_ext;
- }
-
- return (n);
+ SEG *n;
+
+ n = (SEG *) palloc(sizeof(*n));
+
+ /* take max of upper endpoints */
+ if (a->upper > b->upper)
+ {
+ n->upper = a->upper;
+ n->u_sigd = a->u_sigd;
+ n->u_ext = a->u_ext;
+ }
+ else
+ {
+ n->upper = b->upper;
+ n->u_sigd = b->u_sigd;
+ n->u_ext = b->u_ext;
+ }
+
+ /* take min of lower endpoints */
+ if (a->lower < b->lower)
+ {
+ n->lower = a->lower;
+ n->l_sigd = a->l_sigd;
+ n->l_ext = a->l_ext;
+ }
+ else
+ {
+ n->lower = b->lower;
+ n->l_sigd = b->l_sigd;
+ n->l_ext = b->l_ext;
+ }
+
+ return (n);
}
SEG *
-seg_inter(SEG *a, SEG *b)
+seg_inter(SEG * a, SEG * b)
{
- SEG *n;
-
- n = (SEG *) palloc(sizeof(*n));
-
- /* take min of upper endpoints */
- if (a->upper < b->upper)
- {
- n->upper = a->upper;
- n->u_sigd = a->u_sigd;
- n->u_ext = a->u_ext;
- }
- else
- {
- n->upper = b->upper;
- n->u_sigd = b->u_sigd;
- n->u_ext = b->u_ext;
- }
-
- /* take max of lower endpoints */
- if (a->lower > b->lower)
- {
- n->lower = a->lower;
- n->l_sigd = a->l_sigd;
- n->l_ext = a->l_ext;
- }
- else
- {
- n->lower = b->lower;
- n->l_sigd = b->l_sigd;
- n->l_ext = b->l_ext;
- }
-
- return (n);
+ SEG *n;
+
+ n = (SEG *) palloc(sizeof(*n));
+
+ /* take min of upper endpoints */
+ if (a->upper < b->upper)
+ {
+ n->upper = a->upper;
+ n->u_sigd = a->u_sigd;
+ n->u_ext = a->u_ext;
+ }
+ else
+ {
+ n->upper = b->upper;
+ n->u_sigd = b->u_sigd;
+ n->u_ext = b->u_ext;
+ }
+
+ /* take max of lower endpoints */
+ if (a->lower > b->lower)
+ {
+ n->lower = a->lower;
+ n->l_sigd = a->l_sigd;
+ n->l_ext = a->l_ext;
+ }
+ else
+ {
+ n->lower = b->lower;
+ n->l_sigd = b->l_sigd;
+ n->l_ext = b->l_ext;
+ }
+
+ return (n);
}
void
-rt_seg_size(SEG *a, float *size)
+rt_seg_size(SEG * a, float *size)
{
- if (a == (SEG *) NULL || a->upper <= a->lower)
- *size = 0.0;
- else
- *size = (float) abs(a->upper - a->lower);
-
- return;
+ if (a == (SEG *) NULL || a->upper <= a->lower)
+ *size = 0.0;
+ else
+ *size = (float) abs(a->upper - a->lower);
+
+ return;
}
float *
-seg_size(SEG *a)
+seg_size(SEG * a)
{
- float *result;
+ float *result;
+
+ result = (float *) palloc(sizeof(float));
- result = (float *) palloc(sizeof(float));
-
- *result = (float) abs(a->upper - a->lower);
+ *result = (float) abs(a->upper - a->lower);
- return(result);
+ return (result);
}
/*****************************************************************************
- * Miscellaneous operators
+ * Miscellaneous operators
*****************************************************************************/
int32
-seg_cmp(SEG *a, SEG *b)
+seg_cmp(SEG * a, SEG * b)
{
+
/*
* First compare on lower boundary position
*/
- if ( a->lower < b->lower )
+ if (a->lower < b->lower)
return -1;
- if ( a->lower > b->lower )
+ if (a->lower > b->lower)
return 1;
+
/*
* a->lower == b->lower, so consider type of boundary.
*
- * A '-' lower bound is < any other kind (this could only be relevant
- * if -HUGE is used as a regular data value).
- * A '<' lower bound is < any other kind except '-'.
- * A '>' lower bound is > any other kind.
+ * A '-' lower bound is < any other kind (this could only be relevant if
+ * -HUGE is used as a regular data value). A '<' lower bound is < any
+ * other kind except '-'. A '>' lower bound is > any other kind.
*/
- if ( a->l_ext != b->l_ext )
+ if (a->l_ext != b->l_ext)
{
- if ( a->l_ext == '-')
+ if (a->l_ext == '-')
return -1;
- if ( b->l_ext == '-')
+ if (b->l_ext == '-')
return 1;
- if ( a->l_ext == '<')
+ if (a->l_ext == '<')
return -1;
- if ( b->l_ext == '<')
+ if (b->l_ext == '<')
return 1;
- if ( a->l_ext == '>')
+ if (a->l_ext == '>')
return 1;
- if ( b->l_ext == '>')
+ if (b->l_ext == '>')
return -1;
}
+
/*
* For other boundary types, consider # of significant digits first.
*/
- if ( a->l_sigd < b->l_sigd ) /* (a) is blurred and is likely to include (b) */
+ if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include
+ * (b) */
return -1;
- if ( a->l_sigd > b->l_sigd ) /* (a) is less blurred and is likely to be included in (b) */
+ if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
+ * included in (b) */
return 1;
+
/*
* For same # of digits, an approximate boundary is more blurred than
* exact.
*/
- if ( a->l_ext != b->l_ext )
+ if (a->l_ext != b->l_ext)
{
- if ( a->l_ext == '~' ) /* (a) is approximate, while (b) is exact */
+ if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
return -1;
- if ( b->l_ext == '~' )
+ if (b->l_ext == '~')
return 1;
/* can't get here unless data is corrupt */
elog(ERROR, "seg_cmp: bogus lower boundary types %d %d",
@@ -780,50 +826,54 @@ seg_cmp(SEG *a, SEG *b)
/*
* First compare on upper boundary position
*/
- if ( a->upper < b->upper )
+ if (a->upper < b->upper)
return -1;
- if ( a->upper > b->upper )
+ if (a->upper > b->upper)
return 1;
+
/*
* a->upper == b->upper, so consider type of boundary.
*
- * A '-' upper bound is > any other kind (this could only be relevant
- * if HUGE is used as a regular data value).
- * A '<' upper bound is < any other kind.
- * A '>' upper bound is > any other kind except '-'.
+ * A '-' upper bound is > any other kind (this could only be relevant if
+ * HUGE is used as a regular data value). A '<' upper bound is < any
+ * other kind. A '>' upper bound is > any other kind except '-'.
*/
- if ( a->u_ext != b->u_ext )
+ if (a->u_ext != b->u_ext)
{
- if ( a->u_ext == '-')
+ if (a->u_ext == '-')
return 1;
- if ( b->u_ext == '-')
+ if (b->u_ext == '-')
return -1;
- if ( a->u_ext == '<')
+ if (a->u_ext == '<')
return -1;
- if ( b->u_ext == '<')
+ if (b->u_ext == '<')
return 1;
- if ( a->u_ext == '>')
+ if (a->u_ext == '>')
return 1;
- if ( b->u_ext == '>')
+ if (b->u_ext == '>')
return -1;
}
+
/*
* For other boundary types, consider # of significant digits first.
* Note result here is converse of the lower-boundary case.
*/
- if ( a->u_sigd < b->u_sigd ) /* (a) is blurred and is likely to include (b) */
+ if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include
+ * (b) */
return 1;
- if ( a->u_sigd > b->u_sigd ) /* (a) is less blurred and is likely to be included in (b) */
+ if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
+ * included in (b) */
return -1;
+
/*
* For same # of digits, an approximate boundary is more blurred than
* exact. Again, result is converse of lower-boundary case.
*/
- if ( a->u_ext != b->u_ext )
+ if (a->u_ext != b->u_ext)
{
- if ( a->u_ext == '~' ) /* (a) is approximate, while (b) is exact */
+ if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
return 1;
- if ( b->u_ext == '~' )
+ if (b->u_ext == '~')
return -1;
/* can't get here unless data is corrupt */
elog(ERROR, "seg_cmp: bogus upper boundary types %d %d",
@@ -834,40 +884,40 @@ seg_cmp(SEG *a, SEG *b)
}
bool
-seg_lt(SEG *a, SEG *b)
+seg_lt(SEG * a, SEG * b)
{
- return seg_cmp(a, b) < 0;
+ return seg_cmp(a, b) < 0;
}
bool
-seg_le(SEG *a, SEG *b)
+seg_le(SEG * a, SEG * b)
{
- return seg_cmp(a, b) <= 0;
+ return seg_cmp(a, b) <= 0;
}
bool
-seg_gt(SEG *a, SEG *b)
+seg_gt(SEG * a, SEG * b)
{
- return seg_cmp(a, b) > 0;
+ return seg_cmp(a, b) > 0;
}
bool
-seg_ge(SEG *a, SEG *b)
+seg_ge(SEG * a, SEG * b)
{
- return seg_cmp(a, b) >= 0;
+ return seg_cmp(a, b) >= 0;
}
bool
-seg_different(SEG *a, SEG *b)
+seg_different(SEG * a, SEG * b)
{
- return seg_cmp(a, b) != 0;
+ return seg_cmp(a, b) != 0;
}
/*****************************************************************************
- * Auxiliary functions
+ * Auxiliary functions
*****************************************************************************/
/* The purpose of this routine is to print the floating point
@@ -875,126 +925,150 @@ seg_different(SEG *a, SEG *b)
* is similar to %.ng except it prints 8.00 where %.ng would
* print 8
*/
-static int restore ( char * result, float val, int n )
+static int
+restore(char *result, float val, int n)
{
- static char efmt[8] = {'%', '-', '1', '5', '.', '#', 'e', 0};
- char buf[25] = {
- '0', '0', '0', '0', '0',
- '0', '0', '0', '0', '0',
- '0', '0', '0', '0', '0',
- '0', '0', '0', '0', '0',
- '0', '0', '0', '0', '\0'
- };
- char *p;
- char *mant;
- int exp;
- int i, dp, sign;
-
- /* put a cap on the number of siugnificant digits to avoid
- nonsense in the output */
- n = min(n, FLT_DIG);
-
- /* remember the sign */
- sign = ( val < 0 ? 1 : 0 );
-
- efmt[5] = '0' + (n-1)%10; /* makes %-15.(n-1)e -- this format guarantees that
- the exponent is always present */
-
- sprintf(result, efmt, val);
-
- /* trim the spaces left by the %e */
- for( p = result; *p != ' '; p++ ); *p = '\0';
-
- /* get the exponent */
- mant = (char *)strtok( strdup(result), "e" );
- exp = atoi(strtok( NULL, "e" ));
-
- if ( exp == 0 ) {
- /* use the supplied mantyssa with sign */
- strcpy((char *)index(result, 'e'), "");
- }
- else {
- if ( abs( exp ) <= 4 ) {
- /* remove the decimal point from the mantyssa and write the digits to the buf array */
- for( p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++ ) {
- buf[i] = *p;
- if( *p == '.' ) {
- dp = i--; /* skip the decimal point */
- }
- }
- if (dp == 0) dp = i--; /* no decimal point was found in the above for() loop */
-
- if ( exp > 0 ) {
- if ( dp - 10 + exp >= n ) {
- /*
- the decimal point is behind the last significant digit;
- the digits in between must be converted to the exponent
- and the decimal point placed after the first digit
- */
- exp = dp - 10 + exp - n;
- buf[10+n] = '\0';
-
- /* insert the decimal point */
- if ( n > 1 ) {
- dp = 11;
- for ( i = 23; i > dp; i-- ) {
- buf[i] = buf[i-1];
- }
- buf[dp] = '.';
- }
-
- /* adjust the exponent by the number of digits after the decimal point */
- if ( n > 1 ) {
- sprintf(&buf[11+n], "e%d", exp + n - 1);
- }
- else {
- sprintf(&buf[11], "e%d", exp + n - 1);
- }
-
- if ( sign ) {
- buf[9] = '-';
- strcpy(result, &buf[9]);
- }
- else {
- strcpy(result, &buf[10]);
- }
- }
- else { /* insert the decimal point */
- dp += exp;
- for ( i = 23; i > dp; i-- ) {
- buf[i] = buf[i-1];
- }
- buf[11+n] = '\0';
- buf[dp] = '.';
- if ( sign ) {
- buf[9] = '-';
- strcpy(result, &buf[9]);
- }
- else {
- strcpy(result, &buf[10]);
- }
+ static char efmt[8] = {'%', '-', '1', '5', '.', '#', 'e', 0};
+ char buf[25] = {
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '\0'
+ };
+ char *p;
+ char *mant;
+ int exp;
+ int i,
+ dp,
+ sign;
+
+ /*
+ * put a cap on the number of siugnificant digits to avoid nonsense in
+ * the output
+ */
+ n = min(n, FLT_DIG);
+
+ /* remember the sign */
+ sign = (val < 0 ? 1 : 0);
+
+ efmt[5] = '0' + (n - 1) % 10; /* makes %-15.(n-1)e -- this
+ * format guarantees that the
+ * exponent is always present */
+
+ sprintf(result, efmt, val);
+
+ /* trim the spaces left by the %e */
+ for (p = result; *p != ' '; p++);
+ *p = '\0';
+
+ /* get the exponent */
+ mant = (char *) strtok(strdup(result), "e");
+ exp = atoi(strtok(NULL, "e"));
+
+ if (exp == 0)
+ {
+ /* use the supplied mantyssa with sign */
+ strcpy((char *) index(result, 'e'), "");
}
- }
- else { /* exp <= 0 */
- dp += exp - 1;
- buf[10+n] = '\0';
- buf[dp] = '.';
- if ( sign ) {
- buf[dp-2] = '-';
- strcpy(result, &buf[dp-2]);
+ else
+ {
+ if (abs(exp) <= 4)
+ {
+
+ /*
+ * remove the decimal point from the mantyssa and write the
+ * digits to the buf array
+ */
+ for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
+ {
+ buf[i] = *p;
+ if (*p == '.')
+ {
+ dp = i--; /* skip the decimal point */
+ }
+ }
+ if (dp == 0)
+ dp = i--; /* no decimal point was found in the above
+ * for() loop */
+
+ if (exp > 0)
+ {
+ if (dp - 10 + exp >= n)
+ {
+
+ /*
+ * the decimal point is behind the last significant
+ * digit; the digits in between must be converted to
+ * the exponent and the decimal point placed after the
+ * first digit
+ */
+ exp = dp - 10 + exp - n;
+ buf[10 + n] = '\0';
+
+ /* insert the decimal point */
+ if (n > 1)
+ {
+ dp = 11;
+ for (i = 23; i > dp; i--)
+ buf[i] = buf[i - 1];
+ buf[dp] = '.';
+ }
+
+ /*
+ * adjust the exponent by the number of digits after
+ * the decimal point
+ */
+ if (n > 1)
+ sprintf(&buf[11 + n], "e%d", exp + n - 1);
+ else
+ sprintf(&buf[11], "e%d", exp + n - 1);
+
+ if (sign)
+ {
+ buf[9] = '-';
+ strcpy(result, &buf[9]);
+ }
+ else
+ strcpy(result, &buf[10]);
+ }
+ else
+ { /* insert the decimal point */
+ dp += exp;
+ for (i = 23; i > dp; i--)
+ buf[i] = buf[i - 1];
+ buf[11 + n] = '\0';
+ buf[dp] = '.';
+ if (sign)
+ {
+ buf[9] = '-';
+ strcpy(result, &buf[9]);
+ }
+ else
+ strcpy(result, &buf[10]);
+ }
+ }
+ else
+ { /* exp <= 0 */
+ dp += exp - 1;
+ buf[10 + n] = '\0';
+ buf[dp] = '.';
+ if (sign)
+ {
+ buf[dp - 2] = '-';
+ strcpy(result, &buf[dp - 2]);
+ }
+ else
+ strcpy(result, &buf[dp - 1]);
+ }
+ }
+
+ /* do nothing for abs(exp) > 4; %e must be OK */
+ /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
+
+ /* ... this is not done yet. */
}
- else {
- strcpy(result, &buf[dp-1]);
- }
- }
- }
-
- /* do nothing for abs(exp) > 4; %e must be OK */
- /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
-
- /* ... this is not done yet. */
- }
- return ( strlen ( result ) );
+ return (strlen(result));
}
@@ -1003,47 +1077,56 @@ static int restore ( char * result, float val, int n )
*/
bool
-seg_contains_int(SEG *a, int *b)
+seg_contains_int(SEG * a, int *b)
{
- return ( (a->lower <= *b) && (a->upper >= *b) );
+ return ((a->lower <= *b) && (a->upper >= *b));
}
bool
-seg_contains_float4(SEG *a, float4 *b)
+seg_contains_float4(SEG * a, float4 *b)
{
- return ( (a->lower <= *b) && (a->upper >= *b) );
+ return ((a->lower <= *b) && (a->upper >= *b));
}
bool
-seg_contains_float8(SEG *a, float8 *b)
+seg_contains_float8(SEG * a, float8 *b)
{
- return ( (a->lower <= *b) && (a->upper >= *b) );
+ return ((a->lower <= *b) && (a->upper >= *b));
}
-/* find out the number of significant digits in a string representing
+/* find out the number of significant digits in a string representing
* a floating point number
*/
-int significant_digits ( char* s )
+int
+significant_digits(char *s)
{
- char * p = s;
- int n, c, zeroes;
+ char *p = s;
+ int n,
+ c,
+ zeroes;
- zeroes = 1;
- /* skip leading zeroes and sign */
- for ( c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p) );
+ zeroes = 1;
+ /* skip leading zeroes and sign */
+ for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
- /* skip decimal point and following zeroes */
- for ( c = *p; (c == '0' || c == '.' ) && c != 0; c = *(++p) ) {
- if ( c != '.') zeroes++;
- }
+ /* skip decimal point and following zeroes */
+ for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
+ {
+ if (c != '.')
+ zeroes++;
+ }
- /* count significant digits (n) */
- for ( c = *p, n = 0; c != 0; c = *(++p) ) {
- if ( !( (c >= '0' && c <= '9') || (c == '.') ) ) break;
- if ( c != '.') n++;
- }
+ /* count significant digits (n) */
+ for (c = *p, n = 0; c != 0; c = *(++p))
+ {
+ if (!((c >= '0' && c <= '9') || (c == '.')))
+ break;
+ if (c != '.')
+ n++;
+ }
- if (!n) return ( zeroes );
+ if (!n)
+ return (zeroes);
- return( n );
+ return (n);
}