File: gserialized_gist.h

package info (click to toggle)
postgis 2.5.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 75,792 kB
  • sloc: ansic: 139,314; sql: 136,281; xml: 48,954; sh: 4,906; perl: 4,509; makefile: 2,897; python: 1,198; yacc: 441; cpp: 305; lex: 132
file content (152 lines) | stat: -rw-r--r-- 5,263 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <float.h>
/**********************************************************************
**  GIDX structure.
**
**  This is an n-dimensional (practically, the
**  implementation is 2-4 dimensions) box used for index keys. The
**  coordinates are anonymous, so we can have any number of dimensions.
**  The sizeof a GIDX is 1 + 2 * ndims * sizeof(float).
**  The order of values in a GIDX is
**  xmin,xmax,ymin,ymax,zmin,zmax...
*/
typedef struct
{
	int32 varsize;
	float c[1];
} GIDX;

/*
** For some GiST support functions, it is more efficient to allocate
** memory for our GIDX off the stack and cast that memory into a GIDX.
** But, GIDX is variable length, what to do? We'll bake in the assumption
** that no GIDX is more than 4-dimensional for now, and ensure that much
** space is available.
** 4 bytes varsize + 4 dimensions * 2 ordinates * 4 bytes float size = 36 bytes
*/
#define GIDX_MAX_SIZE 36
#define GIDX_MAX_DIM 4


/*
 * This macro is based on PG_FREE_IF_COPY, except that it accepts two pointers.
 * See PG_FREE_IF_COPY comment in src/include/fmgr.h in postgres source code
 * for more details.
 */
#define POSTGIS_FREE_IF_COPY_P(ptrsrc, ptrori) \
	do { \
		if ((Pointer) (ptrsrc) != (Pointer) (ptrori)) \
			pfree(ptrsrc); \
	} while (0)

/**********************************************************************
**  BOX2DF structure.
**
**  This is a 2-dimensional key for simple cartesian indexes,
**  with backwards compatible behavior to previous indexes in
**  PostGIS
*/

typedef struct
{
	float xmin, xmax, ymin, ymax;
} BOX2DF;


/*********************************************************************************
** GIDX support functions.
**
** We put the GIDX support here rather than libgeom because it is a specialized
** type only used for indexing purposes. It also makes use of some PgSQL
** infrastructure like the VARSIZE() macros.
*/

/* allocate a new gidx object on the heap */
GIDX* gidx_new(int ndims) ;

/* Increase the size of a GIDX */
void gidx_expand(GIDX *a, float d);

/* Note empty GIDX */
bool gidx_is_unknown(const GIDX *a);

/* Generate human readable form for GIDX. */
char* gidx_to_string(GIDX *a) ;

/* typedef to correct array-bounds checking for casts to GIDX - do not
   use this ANYWHERE except in the casts below */
typedef float _gidx_float_array[sizeof(float) * 2 * 4];

/* Returns number of dimensions for this GIDX */
#define GIDX_NDIMS(gidx) ((VARSIZE((gidx)) - VARHDRSZ) / (2 * sizeof(float)))
/* Minimum accessor. */
#define GIDX_GET_MIN(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2*(dimension)]
/* Maximum accessor. */
#define GIDX_GET_MAX(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2*(dimension)+1]
/* Minimum setter. */
#define GIDX_SET_MIN(gidx, dimension, value) ((gidx)->c[2*(dimension)] = (value))
/* Maximum setter. */
#define GIDX_SET_MAX(gidx, dimension, value) ((gidx)->c[2*(dimension)+1] = (value))
/* Returns the size required to store a GIDX of requested dimension */
#define GIDX_SIZE(dimensions) (sizeof(int32) + 2*(dimensions)*sizeof(float))

/* Allocate a copy of the box */
BOX2DF* box2df_copy(BOX2DF *b);

/* Grow the first argument to contain the second */
void box2df_merge(BOX2DF *b_union, BOX2DF *b_new);

/* Allocate a copy of the box */
GIDX* gidx_copy(GIDX *b);

/* Grow the first argument to contain the second */
void gidx_merge(GIDX **b_union, GIDX *b_new);

/* Note empty BOX2DF */
bool box2df_is_empty(const BOX2DF *a);

/* Fill in a gbox from a GIDX */
void gbox_from_gidx(GIDX *a, GBOX *gbox, int flags);

/* Fill in a gbox from a BOX2DF */
int box2df_to_gbox_p(BOX2DF *a, GBOX *box);

/*********************************************************************************
** GSERIALIZED support functions.
**
** Fast functions for pulling boxes out of serializations.
*/

/* Pull out the #GIDX bounding box with a absolute minimum system overhead */
int gserialized_datum_get_gidx_p(Datum gserialized_datum, GIDX *gidx);

/* Pull out the gidx bounding box from an already de-toasted geography */
int gserialized_get_gidx_p(const GSERIALIZED *g, GIDX *gidx);
/* Copy a new bounding box into an existing gserialized */
GSERIALIZED* gserialized_set_gidx(GSERIALIZED *g, GIDX *gidx);

/* Given two datums, do they overlap? Computed very fast using embedded boxes. */
/* int gserialized_datum_overlaps(Datum gs1, Datum gs2); */
/* Remove the box from a disk serialization */
GSERIALIZED* gserialized_drop_gidx(GSERIALIZED *g);

bool box2df_contains(const BOX2DF *a, const BOX2DF *b);


void box2df_set_empty(BOX2DF *a);
void box2df_set_finite(BOX2DF *a);
void box2df_validate(BOX2DF *b);
bool box2df_overlaps(const BOX2DF *a, const BOX2DF *b);
bool box2df_overleft(const BOX2DF *a, const BOX2DF *b);
bool box2df_equals(const BOX2DF *a, const BOX2DF *b);
bool box2df_left(const BOX2DF *a, const BOX2DF *b);
bool box2df_right(const BOX2DF *a, const BOX2DF *b);
bool box2df_overright(const BOX2DF *a, const BOX2DF *b);
bool box2df_overbelow(const BOX2DF *a, const BOX2DF *b);
bool box2df_below(const BOX2DF *a, const BOX2DF *b);
bool box2df_above(const BOX2DF *a, const BOX2DF *b);
bool box2df_overabove(const BOX2DF *a, const BOX2DF *b);


bool gidx_contains(GIDX *a, GIDX *b);
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df);