]> granicus.if.org Git - postgresql/blob - contrib/btree_gist/btree_float4.c
Post-PG 10 beta1 pgindent run
[postgresql] / contrib / btree_gist / btree_float4.c
1 /*
2  * contrib/btree_gist/btree_float4.c
3  */
4 #include "postgres.h"
5
6 #include "btree_gist.h"
7 #include "btree_utils_num.h"
8
9 typedef struct float4key
10 {
11         float4          lower;
12         float4          upper;
13 } float4KEY;
14
15 /*
16 ** float4 ops
17 */
18 PG_FUNCTION_INFO_V1(gbt_float4_compress);
19 PG_FUNCTION_INFO_V1(gbt_float4_fetch);
20 PG_FUNCTION_INFO_V1(gbt_float4_union);
21 PG_FUNCTION_INFO_V1(gbt_float4_picksplit);
22 PG_FUNCTION_INFO_V1(gbt_float4_consistent);
23 PG_FUNCTION_INFO_V1(gbt_float4_distance);
24 PG_FUNCTION_INFO_V1(gbt_float4_penalty);
25 PG_FUNCTION_INFO_V1(gbt_float4_same);
26
27 static bool
28 gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo)
29 {
30         return (*((const float4 *) a) > *((const float4 *) b));
31 }
32 static bool
33 gbt_float4ge(const void *a, const void *b, FmgrInfo *flinfo)
34 {
35         return (*((const float4 *) a) >= *((const float4 *) b));
36 }
37 static bool
38 gbt_float4eq(const void *a, const void *b, FmgrInfo *flinfo)
39 {
40         return (*((const float4 *) a) == *((const float4 *) b));
41 }
42 static bool
43 gbt_float4le(const void *a, const void *b, FmgrInfo *flinfo)
44 {
45         return (*((const float4 *) a) <= *((const float4 *) b));
46 }
47 static bool
48 gbt_float4lt(const void *a, const void *b, FmgrInfo *flinfo)
49 {
50         return (*((const float4 *) a) < *((const float4 *) b));
51 }
52
53 static int
54 gbt_float4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
55 {
56         float4KEY  *ia = (float4KEY *) (((const Nsrt *) a)->t);
57         float4KEY  *ib = (float4KEY *) (((const Nsrt *) b)->t);
58
59         if (ia->lower == ib->lower)
60         {
61                 if (ia->upper == ib->upper)
62                         return 0;
63
64                 return (ia->upper > ib->upper) ? 1 : -1;
65         }
66
67         return (ia->lower > ib->lower) ? 1 : -1;
68 }
69
70 static float8
71 gbt_float4_dist(const void *a, const void *b, FmgrInfo *flinfo)
72 {
73         return GET_FLOAT_DISTANCE(float4, a, b);
74 }
75
76
77 static const gbtree_ninfo tinfo =
78 {
79         gbt_t_float4,
80         sizeof(float4),
81         8,                                                      /* sizeof(gbtreekey8) */
82         gbt_float4gt,
83         gbt_float4ge,
84         gbt_float4eq,
85         gbt_float4le,
86         gbt_float4lt,
87         gbt_float4key_cmp,
88         gbt_float4_dist
89 };
90
91
92 PG_FUNCTION_INFO_V1(float4_dist);
93 Datum
94 float4_dist(PG_FUNCTION_ARGS)
95 {
96         float4          a = PG_GETARG_FLOAT4(0);
97         float4          b = PG_GETARG_FLOAT4(1);
98         float4          r;
99
100         r = a - b;
101         CHECKFLOATVAL(r, isinf(a) || isinf(b), true);
102
103         PG_RETURN_FLOAT4(Abs(r));
104 }
105
106
107 /**************************************************
108  * float4 ops
109  **************************************************/
110
111
112 Datum
113 gbt_float4_compress(PG_FUNCTION_ARGS)
114 {
115         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
116
117         PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
118 }
119
120 Datum
121 gbt_float4_fetch(PG_FUNCTION_ARGS)
122 {
123         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
124
125         PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
126 }
127
128 Datum
129 gbt_float4_consistent(PG_FUNCTION_ARGS)
130 {
131         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
132         float4          query = PG_GETARG_FLOAT4(1);
133         StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
134
135         /* Oid          subtype = PG_GETARG_OID(3); */
136         bool       *recheck = (bool *) PG_GETARG_POINTER(4);
137         float4KEY  *kkk = (float4KEY *) DatumGetPointer(entry->key);
138         GBT_NUMKEY_R key;
139
140         /* All cases served by this function are exact */
141         *recheck = false;
142
143         key.lower = (GBT_NUMKEY *) &kkk->lower;
144         key.upper = (GBT_NUMKEY *) &kkk->upper;
145
146         PG_RETURN_BOOL(
147                                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
148                 );
149 }
150
151
152 Datum
153 gbt_float4_distance(PG_FUNCTION_ARGS)
154 {
155         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
156         float4          query = PG_GETARG_FLOAT4(1);
157
158         /* Oid          subtype = PG_GETARG_OID(3); */
159         float4KEY  *kkk = (float4KEY *) DatumGetPointer(entry->key);
160         GBT_NUMKEY_R key;
161
162         key.lower = (GBT_NUMKEY *) &kkk->lower;
163         key.upper = (GBT_NUMKEY *) &kkk->upper;
164
165         PG_RETURN_FLOAT8(
166                                          gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
167                 );
168 }
169
170
171 Datum
172 gbt_float4_union(PG_FUNCTION_ARGS)
173 {
174         GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
175         void       *out = palloc(sizeof(float4KEY));
176
177         *(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY);
178         PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
179 }
180
181
182 Datum
183 gbt_float4_penalty(PG_FUNCTION_ARGS)
184 {
185         float4KEY  *origentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
186         float4KEY  *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
187         float      *result = (float *) PG_GETARG_POINTER(2);
188
189         penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
190
191         PG_RETURN_POINTER(result);
192
193 }
194
195 Datum
196 gbt_float4_picksplit(PG_FUNCTION_ARGS)
197 {
198         PG_RETURN_POINTER(gbt_num_picksplit(
199                                                                         (GistEntryVector *) PG_GETARG_POINTER(0),
200                                                                           (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
201                                                                                 &tinfo, fcinfo->flinfo
202                                                                                 ));
203 }
204
205 Datum
206 gbt_float4_same(PG_FUNCTION_ARGS)
207 {
208         float4KEY  *b1 = (float4KEY *) PG_GETARG_POINTER(0);
209         float4KEY  *b2 = (float4KEY *) PG_GETARG_POINTER(1);
210         bool       *result = (bool *) PG_GETARG_POINTER(2);
211
212         *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
213         PG_RETURN_POINTER(result);
214 }