forked from postgrespro/pgsphere
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpgs_process_moc.h
172 lines (130 loc) · 4.49 KB
/
pgs_process_moc.h
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#ifndef __PGS_PROCESS_MOC_H__
#define __PGS_PROCESS_MOC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* this goes in front to detect the chealpix API break */
#include "pgs_chealpix.h"
#include <c.h> /* PostgreSQL type definitions */
/*
* PG_TOAST_PAGE_FRAGMENT should equal TOAST_MAX_CHUNK_SIZE, but we
* do not want to implicitely include quite a few other Postgres headers
* just for the small gain of getting its value right.
* Usually, TOAST_MAX_CHUNK_SIZE equals 1996.
*
* #include <postgres.h>
* #include <access/tuptoaster.h> // for TOAST_MAX_CHUNK_SIZE
*/
extern int32 smoc_output_type;
typedef void (*pgs_error_handler)(const char*, int);
#define HP64_SIZE (sizeof(hpint64))
#define PG_TOAST_PAGE_FRAGMENT 1996 /* not divisible by HP64_SIZE == 8 */
/* moc_interval: an half-open interval [first, last) of Healpix elements */
typedef struct
{
hpint64 first;
hpint64 second;
} moc_interval;
typedef struct
{
int32 offset; /* counts in units of char, from start of MOC */
char start[HP64_SIZE];
} moc_tree_entry;
#define MOC_INDEX_ALIGN (sizeof(int32))
#define MOC_INTERVAL_SIZE (sizeof(moc_interval))
#define MOC_TREE_ENTRY_SIZE (sizeof(moc_tree_entry))
#define MOC_LEAF_PAGE_LEN (PG_TOAST_PAGE_FRAGMENT / MOC_INTERVAL_SIZE)
#define MOC_TREE_PAGE_LEN (PG_TOAST_PAGE_FRAGMENT / MOC_TREE_ENTRY_SIZE)
/*
* this particular layout should prevent the compiler from introducing unwanted
* padding
*/
typedef struct
{
char vl_len_[4]; /* size of PostgreSQL variable-length data */
uint16 version; /* version of the 'toasty' MOC data structure */
uint8 order; /* actual MOC order */
uint8 depth; /* depth of B+-tree */
hpint64 first; /* first Healpix index in set */
hpint64 last; /* 1 + (last Healpix index in set) */
hpint64 area; /* number of covered Healpix cells */
int32 tree_begin; /* start of B+ tree, past the options block */
int32 data_begin; /* start of Healpix intervals, bypassing the tree */
int32 data[1]; /* no need to optimise for empty MOCs */
} Smoc;
#define MOC_HEADER_VARSIZE (offsetof(Smoc, data))
#define MOC_HEADER_SIZE (MOC_HEADER_VARSIZE - VARHDRSZ)
#define MIN_MOC_SIZE (sizeof(Smoc) - VARHDRSZ)
#define MOC_HEADER_PAGE ((PG_TOAST_PAGE_FRAGMENT) > (MOC_HEADER_VARSIZE) \
? (PG_TOAST_PAGE_FRAGMENT) : (MOC_HEADER_VARSIZE))
#define MOC_BASE(moc) ((char*) &(moc->version))
#define MOC_ENTRY(moc_base, offset) ((moc_tree_entry *)(moc_base + offset))
#define MOC_INTERVAL(moc_base, offset) ((moc_interval *)(moc_base + offset))
#define MOC_MAX_OPTIONS_SIZE 0 /* no options yet */
#define HEALPIX_MAX_ORDER 29
int32
moc_mod_floor(int32, int32);
int32
moc_tree_entry_floor(int32);
int32
moc_interval_floor(int32);
void*
create_moc_in_context(pgs_error_handler);
void
release_moc_in_context(void*, pgs_error_handler);
void
add_to_moc(void*, long, hpint64, hpint64, pgs_error_handler);
void
moc_in_context_set_order(void* moc_in_context, int order);
int
get_moc_size(void*, pgs_error_handler);
void
create_moc_release_context(void*, Smoc*, pgs_error_handler);
typedef struct
{
void* context;
size_t out_size;
} moc_out_data;
moc_out_data
create_moc_out_context(Smoc*, int32, pgs_error_handler);
/* for the final smoc_out() using a proper Postgres memory context */
void
release_moc_out_context(moc_out_data, pgs_error_handler);
void
print_moc_release_context(moc_out_data, char*, pgs_error_handler);
size_t
get_moc_debug(const char**, pgs_error_handler);
void
moc_debug_log(pgs_error_handler, const char *, ...)
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
;
void
moc_debug_clear(pgs_error_handler);
moc_tree_entry*
entry_lower_bound(moc_tree_entry*, moc_tree_entry*, hpint64);
moc_interval*
interval_lower_bound(moc_interval*, moc_interval*, hpint64);
void
moc_union(void* moc_in_context, Smoc* moc_a, int32 moc_a_end, Smoc* moc_b, int32 moc_b_end,
pgs_error_handler error_out);
void
moc_intersection(void* moc_in_context, Smoc* moc_a, int32 moc_a_end, Smoc* moc_b, int32 moc_b_end,
pgs_error_handler error_out);
void
moc_degrade(void* moc_in_context, int order, Smoc* moc_a, int32 moc_a_end,
pgs_error_handler error_out);
void
moc_healpix(void* moc_in_context, int order, hpint64 first, hpint64 last,
pgs_error_handler error_out);
void
moc_disc(void* moc_in_context, int order, double theta, double phi, double radius,
pgs_error_handler error_out);
void
moc_polygon(void* moc_in_context, int order, int32 npts, float8* polygon,
pgs_error_handler error_out);
#ifdef __cplusplus
}
#endif
#endif