File: gserialized_gist.h

package info (click to toggle)
postgis 2.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 58,660 kB
  • ctags: 10,181
  • sloc: ansic: 132,858; sql: 131,148; xml: 46,460; sh: 4,832; perl: 4,476; makefile: 2,749; python: 1,198; yacc: 442; lex: 131
file content (113 lines) | stat: -rw-r--r-- 3,967 bytes parent folder | download | duplicates (2)
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

/**********************************************************************
**  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);


/* 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))

/*********************************************************************************
** 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(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);
bool gidx_contains(GIDX *a, GIDX *b);
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df);