PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
network_gist.c File Reference
#include "postgres.h"
#include <sys/socket.h>
#include "access/gist.h"
#include "access/stratnum.h"
#include "utils/fmgrprotos.h"
#include "utils/inet.h"
#include "varatt.h"
Include dependency graph for network_gist.c:

Go to the source code of this file.

Data Structures

struct  GistInetKey
 

Macros

#define INETSTRAT_OVERLAPS   RTOverlapStrategyNumber
 
#define INETSTRAT_EQ   RTEqualStrategyNumber
 
#define INETSTRAT_NE   RTNotEqualStrategyNumber
 
#define INETSTRAT_LT   RTLessStrategyNumber
 
#define INETSTRAT_LE   RTLessEqualStrategyNumber
 
#define INETSTRAT_GT   RTGreaterStrategyNumber
 
#define INETSTRAT_GE   RTGreaterEqualStrategyNumber
 
#define INETSTRAT_SUB   RTSubStrategyNumber
 
#define INETSTRAT_SUBEQ   RTSubEqualStrategyNumber
 
#define INETSTRAT_SUP   RTSuperStrategyNumber
 
#define INETSTRAT_SUPEQ   RTSuperEqualStrategyNumber
 
#define DatumGetInetKeyP(X)   ((GistInetKey *) DatumGetPointer(X))
 
#define InetKeyPGetDatum(X)   PointerGetDatum(X)
 
#define gk_ip_family(gkptr)   ((gkptr)->family)
 
#define gk_ip_minbits(gkptr)   ((gkptr)->minbits)
 
#define gk_ip_commonbits(gkptr)   ((gkptr)->commonbits)
 
#define gk_ip_addr(gkptr)   ((gkptr)->ipaddr)
 
#define ip_family_maxbits(fam)   ((fam) == PGSQL_AF_INET6 ? 128 : 32)
 
#define gk_ip_addrsize(gkptr)    (gk_ip_family(gkptr) == PGSQL_AF_INET6 ? 16 : 4)
 
#define gk_ip_maxbits(gkptr)    ip_family_maxbits(gk_ip_family(gkptr))
 
#define SET_GK_VARSIZE(dst)    SET_VARSIZE_SHORT(dst, offsetof(GistInetKey, ipaddr) + gk_ip_addrsize(dst))
 

Typedefs

typedef struct GistInetKey GistInetKey
 

Functions

Datum inet_gist_consistent (PG_FUNCTION_ARGS)
 
static void calc_inet_union_params (GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
 
static void calc_inet_union_params_indexed (GISTENTRY *ent, OffsetNumber *offsets, int noffsets, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
 
static GistInetKeybuild_inet_union_key (int family, int minbits, int commonbits, unsigned char *addr)
 
Datum inet_gist_union (PG_FUNCTION_ARGS)
 
Datum inet_gist_compress (PG_FUNCTION_ARGS)
 
Datum inet_gist_fetch (PG_FUNCTION_ARGS)
 
Datum inet_gist_penalty (PG_FUNCTION_ARGS)
 
Datum inet_gist_picksplit (PG_FUNCTION_ARGS)
 
Datum inet_gist_same (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ DatumGetInetKeyP

#define DatumGetInetKeyP (   X)    ((GistInetKey *) DatumGetPointer(X))

Definition at line 88 of file network_gist.c.

◆ gk_ip_addr

#define gk_ip_addr (   gkptr)    ((gkptr)->ipaddr)

Definition at line 99 of file network_gist.c.

◆ gk_ip_addrsize

#define gk_ip_addrsize (   gkptr)     (gk_ip_family(gkptr) == PGSQL_AF_INET6 ? 16 : 4)

Definition at line 103 of file network_gist.c.

◆ gk_ip_commonbits

#define gk_ip_commonbits (   gkptr)    ((gkptr)->commonbits)

Definition at line 98 of file network_gist.c.

◆ gk_ip_family

#define gk_ip_family (   gkptr)    ((gkptr)->family)

Definition at line 96 of file network_gist.c.

◆ gk_ip_maxbits

#define gk_ip_maxbits (   gkptr)     ip_family_maxbits(gk_ip_family(gkptr))

Definition at line 105 of file network_gist.c.

◆ gk_ip_minbits

#define gk_ip_minbits (   gkptr)    ((gkptr)->minbits)

Definition at line 97 of file network_gist.c.

◆ InetKeyPGetDatum

#define InetKeyPGetDatum (   X)    PointerGetDatum(X)

Definition at line 89 of file network_gist.c.

◆ INETSTRAT_EQ

#define INETSTRAT_EQ   RTEqualStrategyNumber

Definition at line 60 of file network_gist.c.

◆ INETSTRAT_GE

#define INETSTRAT_GE   RTGreaterEqualStrategyNumber

Definition at line 65 of file network_gist.c.

◆ INETSTRAT_GT

#define INETSTRAT_GT   RTGreaterStrategyNumber

Definition at line 64 of file network_gist.c.

◆ INETSTRAT_LE

#define INETSTRAT_LE   RTLessEqualStrategyNumber

Definition at line 63 of file network_gist.c.

◆ INETSTRAT_LT

#define INETSTRAT_LT   RTLessStrategyNumber

Definition at line 62 of file network_gist.c.

◆ INETSTRAT_NE

#define INETSTRAT_NE   RTNotEqualStrategyNumber

Definition at line 61 of file network_gist.c.

◆ INETSTRAT_OVERLAPS

#define INETSTRAT_OVERLAPS   RTOverlapStrategyNumber

Definition at line 59 of file network_gist.c.

◆ INETSTRAT_SUB

#define INETSTRAT_SUB   RTSubStrategyNumber

Definition at line 66 of file network_gist.c.

◆ INETSTRAT_SUBEQ

#define INETSTRAT_SUBEQ   RTSubEqualStrategyNumber

Definition at line 67 of file network_gist.c.

◆ INETSTRAT_SUP

#define INETSTRAT_SUP   RTSuperStrategyNumber

Definition at line 68 of file network_gist.c.

◆ INETSTRAT_SUPEQ

#define INETSTRAT_SUPEQ   RTSuperEqualStrategyNumber

Definition at line 69 of file network_gist.c.

◆ ip_family_maxbits

#define ip_family_maxbits (   fam)    ((fam) == PGSQL_AF_INET6 ? 128 : 32)

Definition at line 100 of file network_gist.c.

◆ SET_GK_VARSIZE

#define SET_GK_VARSIZE (   dst)     SET_VARSIZE_SHORT(dst, offsetof(GistInetKey, ipaddr) + gk_ip_addrsize(dst))

Definition at line 107 of file network_gist.c.

Typedef Documentation

◆ GistInetKey

typedef struct GistInetKey GistInetKey

Function Documentation

◆ build_inet_union_key()

static GistInetKey * build_inet_union_key ( int  family,
int  minbits,
int  commonbits,
unsigned char *  addr 
)
static

Definition at line 472 of file network_gist.c.

474{
475 GistInetKey *result;
476
477 /* Make sure any unused bits are zeroed. */
478 result = (GistInetKey *) palloc0(sizeof(GistInetKey));
479
480 gk_ip_family(result) = family;
481 gk_ip_minbits(result) = minbits;
482 gk_ip_commonbits(result) = commonbits;
483
484 /* Clone appropriate bytes of the address. */
485 if (commonbits > 0)
486 memcpy(gk_ip_addr(result), addr, (commonbits + 7) / 8);
487
488 /* Clean any unwanted bits in the last partial byte. */
489 if (commonbits % 8 != 0)
490 gk_ip_addr(result)[commonbits / 8] &= ~(0xFF >> (commonbits % 8));
491
492 /* Set varlena header correctly. */
493 SET_GK_VARSIZE(result);
494
495 return result;
496}
void * palloc0(Size size)
Definition: mcxt.c:1347
#define gk_ip_commonbits(gkptr)
Definition: network_gist.c:98
#define gk_ip_family(gkptr)
Definition: network_gist.c:96
#define gk_ip_addr(gkptr)
Definition: network_gist.c:99
#define SET_GK_VARSIZE(dst)
Definition: network_gist.c:107
#define gk_ip_minbits(gkptr)
Definition: network_gist.c:97

References gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, palloc0(), and SET_GK_VARSIZE.

Referenced by inet_gist_picksplit(), and inet_gist_union().

◆ calc_inet_union_params()

static void calc_inet_union_params ( GISTENTRY ent,
int  m,
int  n,
int *  minfamily_p,
int *  maxfamily_p,
int *  minbits_p,
int *  commonbits_p 
)
static

Definition at line 345 of file network_gist.c.

351{
352 int minfamily,
353 maxfamily,
354 minbits,
355 commonbits;
356 unsigned char *addr;
357 GistInetKey *tmp;
358 int i;
359
360 /* Must be at least one key. */
361 Assert(m <= n);
362
363 /* Initialize variables using the first key. */
364 tmp = DatumGetInetKeyP(ent[m].key);
365 minfamily = maxfamily = gk_ip_family(tmp);
366 minbits = gk_ip_minbits(tmp);
367 commonbits = gk_ip_commonbits(tmp);
368 addr = gk_ip_addr(tmp);
369
370 /* Scan remaining keys. */
371 for (i = m + 1; i <= n; i++)
372 {
373 tmp = DatumGetInetKeyP(ent[i].key);
374
375 /* Determine range of family numbers */
376 if (minfamily > gk_ip_family(tmp))
377 minfamily = gk_ip_family(tmp);
378 if (maxfamily < gk_ip_family(tmp))
379 maxfamily = gk_ip_family(tmp);
380
381 /* Find minimum minbits */
382 if (minbits > gk_ip_minbits(tmp))
383 minbits = gk_ip_minbits(tmp);
384
385 /* Find minimum number of bits in common */
386 if (commonbits > gk_ip_commonbits(tmp))
387 commonbits = gk_ip_commonbits(tmp);
388 if (commonbits > 0)
389 commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
390 }
391
392 /* Force minbits/commonbits to zero if more than one family. */
393 if (minfamily != maxfamily)
394 minbits = commonbits = 0;
395
396 *minfamily_p = minfamily;
397 *maxfamily_p = maxfamily;
398 *minbits_p = minbits;
399 *commonbits_p = commonbits;
400}
Assert(PointerIsAligned(start, uint64))
int i
Definition: isn.c:77
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1570
#define DatumGetInetKeyP(X)
Definition: network_gist.c:88

References Assert(), bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, i, and sort-test::key.

Referenced by inet_gist_picksplit(), and inet_gist_union().

◆ calc_inet_union_params_indexed()

static void calc_inet_union_params_indexed ( GISTENTRY ent,
OffsetNumber offsets,
int  noffsets,
int *  minfamily_p,
int *  maxfamily_p,
int *  minbits_p,
int *  commonbits_p 
)
static

Definition at line 407 of file network_gist.c.

413{
414 int minfamily,
415 maxfamily,
416 minbits,
417 commonbits;
418 unsigned char *addr;
419 GistInetKey *tmp;
420 int i;
421
422 /* Must be at least one key. */
423 Assert(noffsets > 0);
424
425 /* Initialize variables using the first key. */
426 tmp = DatumGetInetKeyP(ent[offsets[0]].key);
427 minfamily = maxfamily = gk_ip_family(tmp);
428 minbits = gk_ip_minbits(tmp);
429 commonbits = gk_ip_commonbits(tmp);
430 addr = gk_ip_addr(tmp);
431
432 /* Scan remaining keys. */
433 for (i = 1; i < noffsets; i++)
434 {
435 tmp = DatumGetInetKeyP(ent[offsets[i]].key);
436
437 /* Determine range of family numbers */
438 if (minfamily > gk_ip_family(tmp))
439 minfamily = gk_ip_family(tmp);
440 if (maxfamily < gk_ip_family(tmp))
441 maxfamily = gk_ip_family(tmp);
442
443 /* Find minimum minbits */
444 if (minbits > gk_ip_minbits(tmp))
445 minbits = gk_ip_minbits(tmp);
446
447 /* Find minimum number of bits in common */
448 if (commonbits > gk_ip_commonbits(tmp))
449 commonbits = gk_ip_commonbits(tmp);
450 if (commonbits > 0)
451 commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
452 }
453
454 /* Force minbits/commonbits to zero if more than one family. */
455 if (minfamily != maxfamily)
456 minbits = commonbits = 0;
457
458 *minfamily_p = minfamily;
459 *maxfamily_p = maxfamily;
460 *minbits_p = minbits;
461 *commonbits_p = commonbits;
462}

References Assert(), bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, i, and sort-test::key.

Referenced by inet_gist_picksplit().

◆ inet_gist_compress()

Datum inet_gist_compress ( PG_FUNCTION_ARGS  )

Definition at line 542 of file network_gist.c.

543{
544 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
545 GISTENTRY *retval;
546
547 if (entry->leafkey)
548 {
549 retval = palloc(sizeof(GISTENTRY));
550 if (DatumGetPointer(entry->key) != NULL)
551 {
552 inet *in = DatumGetInetPP(entry->key);
553 GistInetKey *r;
554
555 r = (GistInetKey *) palloc0(sizeof(GistInetKey));
556
557 gk_ip_family(r) = ip_family(in);
558 gk_ip_minbits(r) = ip_bits(in);
560 memcpy(gk_ip_addr(r), ip_addr(in), gk_ip_addrsize(r));
562
563 gistentryinit(*retval, PointerGetDatum(r),
564 entry->rel, entry->page,
565 entry->offset, false);
566 }
567 else
568 {
569 gistentryinit(*retval, (Datum) 0,
570 entry->rel, entry->page,
571 entry->offset, false);
572 }
573 }
574 else
575 retval = entry;
576 PG_RETURN_POINTER(retval);
577}
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:245
void * palloc(Size size)
Definition: mcxt.c:1317
#define gk_ip_maxbits(gkptr)
Definition: network_gist.c:105
#define gk_ip_addrsize(gkptr)
Definition: network_gist.c:103
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
OffsetNumber offset
Definition: gist.h:164
Datum key
Definition: gist.h:161
Page page
Definition: gist.h:163
Relation rel
Definition: gist.h:162
bool leafkey
Definition: gist.h:165
Definition: inet.h:53
static inet * DatumGetInetPP(Datum X)
Definition: inet.h:123
#define ip_addr(inetptr)
Definition: inet.h:77
#define ip_family(inetptr)
Definition: inet.h:71
#define ip_bits(inetptr)
Definition: inet.h:74

References DatumGetInetPP(), DatumGetPointer(), gistentryinit, gk_ip_addr, gk_ip_addrsize, gk_ip_commonbits, gk_ip_family, gk_ip_maxbits, gk_ip_minbits, ip_addr, ip_bits, ip_family, GISTENTRY::key, GISTENTRY::leafkey, GISTENTRY::offset, GISTENTRY::page, palloc(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), GISTENTRY::rel, and SET_GK_VARSIZE.

◆ inet_gist_consistent()

Datum inet_gist_consistent ( PG_FUNCTION_ARGS  )

Definition at line 115 of file network_gist.c.

116{
118 inet *query = PG_GETARG_INET_PP(1);
120
121 /* Oid subtype = PG_GETARG_OID(3); */
122 bool *recheck = (bool *) PG_GETARG_POINTER(4);
124 int minbits,
125 order;
126
127 /* All operators served by this function are exact. */
128 *recheck = false;
129
130 /*
131 * Check 0: different families
132 *
133 * If key represents multiple address families, its children could match
134 * anything. This can only happen on an inner index page.
135 */
136 if (gk_ip_family(key) == 0)
137 {
138 Assert(!GIST_LEAF(ent));
139 PG_RETURN_BOOL(true);
140 }
141
142 /*
143 * Check 1: different families
144 *
145 * Matching families do not help any of the strategies.
146 */
147 if (gk_ip_family(key) != ip_family(query))
148 {
149 switch (strategy)
150 {
151 case INETSTRAT_LT:
152 case INETSTRAT_LE:
153 if (gk_ip_family(key) < ip_family(query))
154 PG_RETURN_BOOL(true);
155 break;
156
157 case INETSTRAT_GE:
158 case INETSTRAT_GT:
159 if (gk_ip_family(key) > ip_family(query))
160 PG_RETURN_BOOL(true);
161 break;
162
163 case INETSTRAT_NE:
164 PG_RETURN_BOOL(true);
165 }
166 /* For all other cases, we can be sure there is no match */
167 PG_RETURN_BOOL(false);
168 }
169
170 /*
171 * Check 2: network bit count
172 *
173 * Network bit count (ip_bits) helps to check leaves for sub network and
174 * sup network operators. At non-leaf nodes, we know every child value
175 * has ip_bits >= gk_ip_minbits(key), so we can avoid descending in some
176 * cases too.
177 */
178 switch (strategy)
179 {
180 case INETSTRAT_SUB:
181 if (GIST_LEAF(ent) && gk_ip_minbits(key) <= ip_bits(query))
182 PG_RETURN_BOOL(false);
183 break;
184
185 case INETSTRAT_SUBEQ:
186 if (GIST_LEAF(ent) && gk_ip_minbits(key) < ip_bits(query))
187 PG_RETURN_BOOL(false);
188 break;
189
190 case INETSTRAT_SUPEQ:
191 case INETSTRAT_EQ:
192 if (gk_ip_minbits(key) > ip_bits(query))
193 PG_RETURN_BOOL(false);
194 break;
195
196 case INETSTRAT_SUP:
197 if (gk_ip_minbits(key) >= ip_bits(query))
198 PG_RETURN_BOOL(false);
199 break;
200 }
201
202 /*
203 * Check 3: common network bits
204 *
205 * Compare available common prefix bits to the query, but not beyond
206 * either the query's netmask or the minimum netmask among the represented
207 * values. If these bits don't match the query, we have our answer (and
208 * may or may not need to descend, depending on the operator). If they do
209 * match, and we are not at a leaf, we descend in all cases.
210 *
211 * Note this is the final check for operators that only consider the
212 * network part of the address.
213 */
215 minbits = Min(minbits, ip_bits(query));
216
217 order = bitncmp(gk_ip_addr(key), ip_addr(query), minbits);
218
219 switch (strategy)
220 {
221 case INETSTRAT_SUB:
222 case INETSTRAT_SUBEQ:
224 case INETSTRAT_SUPEQ:
225 case INETSTRAT_SUP:
226 PG_RETURN_BOOL(order == 0);
227
228 case INETSTRAT_LT:
229 case INETSTRAT_LE:
230 if (order > 0)
231 PG_RETURN_BOOL(false);
232 if (order < 0 || !GIST_LEAF(ent))
233 PG_RETURN_BOOL(true);
234 break;
235
236 case INETSTRAT_EQ:
237 if (order != 0)
238 PG_RETURN_BOOL(false);
239 if (!GIST_LEAF(ent))
240 PG_RETURN_BOOL(true);
241 break;
242
243 case INETSTRAT_GE:
244 case INETSTRAT_GT:
245 if (order < 0)
246 PG_RETURN_BOOL(false);
247 if (order > 0 || !GIST_LEAF(ent))
248 PG_RETURN_BOOL(true);
249 break;
250
251 case INETSTRAT_NE:
252 if (order != 0 || !GIST_LEAF(ent))
253 PG_RETURN_BOOL(true);
254 break;
255 }
256
257 /*
258 * Remaining checks are only for leaves and basic comparison strategies.
259 * See network_cmp_internal() in network.c for the implementation we need
260 * to match. Note that in a leaf key, commonbits should equal the address
261 * length, so we compared the whole network parts above.
262 */
263 Assert(GIST_LEAF(ent));
264
265 /*
266 * Check 4: network bit count
267 *
268 * Next step is to compare netmask widths.
269 */
270 switch (strategy)
271 {
272 case INETSTRAT_LT:
273 case INETSTRAT_LE:
274 if (gk_ip_minbits(key) < ip_bits(query))
275 PG_RETURN_BOOL(true);
276 if (gk_ip_minbits(key) > ip_bits(query))
277 PG_RETURN_BOOL(false);
278 break;
279
280 case INETSTRAT_EQ:
281 if (gk_ip_minbits(key) != ip_bits(query))
282 PG_RETURN_BOOL(false);
283 break;
284
285 case INETSTRAT_GE:
286 case INETSTRAT_GT:
287 if (gk_ip_minbits(key) > ip_bits(query))
288 PG_RETURN_BOOL(true);
289 if (gk_ip_minbits(key) < ip_bits(query))
290 PG_RETURN_BOOL(false);
291 break;
292
293 case INETSTRAT_NE:
294 if (gk_ip_minbits(key) != ip_bits(query))
295 PG_RETURN_BOOL(true);
296 break;
297 }
298
299 /*
300 * Check 5: whole address
301 *
302 * Netmask bit counts are the same, so check all the address bits.
303 */
304 order = bitncmp(gk_ip_addr(key), ip_addr(query), gk_ip_maxbits(key));
305
306 switch (strategy)
307 {
308 case INETSTRAT_LT:
309 PG_RETURN_BOOL(order < 0);
310
311 case INETSTRAT_LE:
312 PG_RETURN_BOOL(order <= 0);
313
314 case INETSTRAT_EQ:
315 PG_RETURN_BOOL(order == 0);
316
317 case INETSTRAT_GE:
318 PG_RETURN_BOOL(order >= 0);
319
320 case INETSTRAT_GT:
321 PG_RETURN_BOOL(order > 0);
322
323 case INETSTRAT_NE:
324 PG_RETURN_BOOL(order != 0);
325 }
326
327 elog(ERROR, "unknown strategy for inet GiST");
328 PG_RETURN_BOOL(false); /* keep compiler quiet */
329}
#define Min(x, y)
Definition: c.h:975
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:171
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1536
#define INETSTRAT_NE
Definition: network_gist.c:61
#define INETSTRAT_SUPEQ
Definition: network_gist.c:69
#define INETSTRAT_LT
Definition: network_gist.c:62
#define INETSTRAT_SUBEQ
Definition: network_gist.c:67
#define INETSTRAT_SUP
Definition: network_gist.c:68
#define INETSTRAT_GT
Definition: network_gist.c:64
#define INETSTRAT_EQ
Definition: network_gist.c:60
#define INETSTRAT_SUB
Definition: network_gist.c:66
#define INETSTRAT_GE
Definition: network_gist.c:65
#define INETSTRAT_OVERLAPS
Definition: network_gist.c:59
#define INETSTRAT_LE
Definition: network_gist.c:63
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_INET_PP(n)
Definition: inet.h:134

References Assert(), bitncmp(), DatumGetInetKeyP, elog, ERROR, GIST_LEAF, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_maxbits, gk_ip_minbits, INETSTRAT_EQ, INETSTRAT_GE, INETSTRAT_GT, INETSTRAT_LE, INETSTRAT_LT, INETSTRAT_NE, INETSTRAT_OVERLAPS, INETSTRAT_SUB, INETSTRAT_SUBEQ, INETSTRAT_SUP, INETSTRAT_SUPEQ, ip_addr, ip_bits, ip_family, GISTENTRY::key, sort-test::key, Min, PG_GETARG_INET_PP, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

◆ inet_gist_fetch()

Datum inet_gist_fetch ( PG_FUNCTION_ARGS  )

Definition at line 590 of file network_gist.c.

591{
592 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
594 GISTENTRY *retval;
595 inet *dst;
596
597 dst = (inet *) palloc0(sizeof(inet));
598
599 ip_family(dst) = gk_ip_family(key);
600 ip_bits(dst) = gk_ip_minbits(key);
601 memcpy(ip_addr(dst), gk_ip_addr(key), ip_addrsize(dst));
602 SET_INET_VARSIZE(dst);
603
604 retval = palloc(sizeof(GISTENTRY));
605 gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page,
606 entry->offset, false);
607
608 PG_RETURN_POINTER(retval);
609}
static Datum InetPGetDatum(const inet *X)
Definition: inet.h:129
#define SET_INET_VARSIZE(dst)
Definition: inet.h:86
#define ip_addrsize(inetptr)
Definition: inet.h:80

References DatumGetInetKeyP, gistentryinit, gk_ip_addr, gk_ip_family, gk_ip_minbits, InetPGetDatum(), ip_addr, ip_addrsize, ip_bits, ip_family, GISTENTRY::key, sort-test::key, GISTENTRY::offset, GISTENTRY::page, palloc(), palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, GISTENTRY::rel, and SET_INET_VARSIZE.

◆ inet_gist_penalty()

Datum inet_gist_penalty ( PG_FUNCTION_ARGS  )

Definition at line 620 of file network_gist.c.

621{
622 GISTENTRY *origent = (GISTENTRY *) PG_GETARG_POINTER(0);
623 GISTENTRY *newent = (GISTENTRY *) PG_GETARG_POINTER(1);
624 float *penalty = (float *) PG_GETARG_POINTER(2);
625 GistInetKey *orig = DatumGetInetKeyP(origent->key),
626 *new = DatumGetInetKeyP(newent->key);
627 int commonbits;
628
629 if (gk_ip_family(orig) == gk_ip_family(new))
630 {
631 if (gk_ip_minbits(orig) <= gk_ip_minbits(new))
632 {
633 commonbits = bitncommon(gk_ip_addr(orig), gk_ip_addr(new),
634 Min(gk_ip_commonbits(orig),
635 gk_ip_commonbits(new)));
636 if (commonbits > 0)
637 *penalty = 1.0f / commonbits;
638 else
639 *penalty = 2;
640 }
641 else
642 *penalty = 3;
643 }
644 else
645 *penalty = 4;
646
647 PG_RETURN_POINTER(penalty);
648}

References bitncommon(), DatumGetInetKeyP, gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, GISTENTRY::key, Min, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ inet_gist_picksplit()

Datum inet_gist_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 663 of file network_gist.c.

664{
667 GISTENTRY *ent = entryvec->vector;
668 int minfamily,
669 maxfamily,
670 minbits,
671 commonbits;
672 unsigned char *addr;
673 GistInetKey *tmp,
674 *left_union,
675 *right_union;
676 int maxoff,
677 nbytes;
679 *left,
680 *right;
681
682 maxoff = entryvec->n - 1;
683 nbytes = (maxoff + 1) * sizeof(OffsetNumber);
684
685 left = (OffsetNumber *) palloc(nbytes);
686 right = (OffsetNumber *) palloc(nbytes);
687
688 splitvec->spl_left = left;
689 splitvec->spl_right = right;
690
691 splitvec->spl_nleft = 0;
692 splitvec->spl_nright = 0;
693
694 /* Determine parameters of the union of all the inputs. */
696 &minfamily, &maxfamily,
697 &minbits, &commonbits);
698
699 if (minfamily != maxfamily)
700 {
701 /* Multiple families, so split by family. */
702 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
703 {
704 /*
705 * If there's more than 2 families, all but maxfamily go into the
706 * left union. This could only happen if the inputs include some
707 * IPv4, some IPv6, and some already-multiple-family unions.
708 */
709 tmp = DatumGetInetKeyP(ent[i].key);
710 if (gk_ip_family(tmp) != maxfamily)
711 left[splitvec->spl_nleft++] = i;
712 else
713 right[splitvec->spl_nright++] = i;
714 }
715 }
716 else
717 {
718 /*
719 * Split on the next bit after the common bits. If that yields a
720 * trivial split, try the next bit position to the right. Repeat till
721 * success; or if we run out of bits, do an arbitrary 50-50 split.
722 */
723 int maxbits = ip_family_maxbits(minfamily);
724
725 while (commonbits < maxbits)
726 {
727 /* Split using the commonbits'th bit position. */
728 int bitbyte = commonbits / 8;
729 int bitmask = 0x80 >> (commonbits % 8);
730
731 splitvec->spl_nleft = splitvec->spl_nright = 0;
732
733 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
734 {
735 tmp = DatumGetInetKeyP(ent[i].key);
736 addr = gk_ip_addr(tmp);
737 if ((addr[bitbyte] & bitmask) == 0)
738 left[splitvec->spl_nleft++] = i;
739 else
740 right[splitvec->spl_nright++] = i;
741 }
742
743 if (splitvec->spl_nleft > 0 && splitvec->spl_nright > 0)
744 break; /* success */
745 commonbits++;
746 }
747
748 if (commonbits >= maxbits)
749 {
750 /* Failed ... do a 50-50 split. */
751 splitvec->spl_nleft = splitvec->spl_nright = 0;
752
753 for (i = FirstOffsetNumber; i <= maxoff / 2; i = OffsetNumberNext(i))
754 {
755 left[splitvec->spl_nleft++] = i;
756 }
757 for (; i <= maxoff; i = OffsetNumberNext(i))
758 {
759 right[splitvec->spl_nright++] = i;
760 }
761 }
762 }
763
764 /*
765 * Compute the union value for each side from scratch. In most cases we
766 * could approximate the union values with what we already know, but this
767 * ensures that each side has minbits and commonbits set as high as
768 * possible.
769 */
770 calc_inet_union_params_indexed(ent, left, splitvec->spl_nleft,
771 &minfamily, &maxfamily,
772 &minbits, &commonbits);
773 if (minfamily != maxfamily)
774 minfamily = 0;
775 tmp = DatumGetInetKeyP(ent[left[0]].key);
776 addr = gk_ip_addr(tmp);
777 left_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
778 splitvec->spl_ldatum = PointerGetDatum(left_union);
779
780 calc_inet_union_params_indexed(ent, right, splitvec->spl_nright,
781 &minfamily, &maxfamily,
782 &minbits, &commonbits);
783 if (minfamily != maxfamily)
784 minfamily = 0;
785 tmp = DatumGetInetKeyP(ent[right[0]].key);
786 addr = gk_ip_addr(tmp);
787 right_union = build_inet_union_key(minfamily, minbits, commonbits, addr);
788 splitvec->spl_rdatum = PointerGetDatum(right_union);
789
790 PG_RETURN_POINTER(splitvec);
791}
static void calc_inet_union_params(GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
Definition: network_gist.c:345
static void calc_inet_union_params_indexed(GISTENTRY *ent, OffsetNumber *offsets, int noffsets, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
Definition: network_gist.c:407
static GistInetKey * build_inet_union_key(int family, int minbits, int commonbits, unsigned char *addr)
Definition: network_gist.c:472
#define ip_family_maxbits(fam)
Definition: network_gist.c:100
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
int spl_nleft
Definition: gist.h:144
OffsetNumber * spl_right
Definition: gist.h:148
Datum spl_ldatum
Definition: gist.h:145
Datum spl_rdatum
Definition: gist.h:150
int spl_nright
Definition: gist.h:149
OffsetNumber * spl_left
Definition: gist.h:143
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:237
int32 n
Definition: gist.h:236

References build_inet_union_key(), calc_inet_union_params(), calc_inet_union_params_indexed(), DatumGetInetKeyP, FirstOffsetNumber, gk_ip_addr, gk_ip_family, i, ip_family_maxbits, sort-test::key, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and GistEntryVector::vector.

◆ inet_gist_same()

Datum inet_gist_same ( PG_FUNCTION_ARGS  )

Definition at line 797 of file network_gist.c.

798{
801 bool *result = (bool *) PG_GETARG_POINTER(2);
802
803 *result = (gk_ip_family(left) == gk_ip_family(right) &&
804 gk_ip_minbits(left) == gk_ip_minbits(right) &&
805 gk_ip_commonbits(left) == gk_ip_commonbits(right) &&
806 memcmp(gk_ip_addr(left), gk_ip_addr(right),
807 gk_ip_addrsize(left)) == 0);
808
809 PG_RETURN_POINTER(result);
810}
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268

References DatumGetInetKeyP, gk_ip_addr, gk_ip_addrsize, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, PG_GETARG_DATUM, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ inet_gist_union()

Datum inet_gist_union ( PG_FUNCTION_ARGS  )

Definition at line 505 of file network_gist.c.

506{
508 GISTENTRY *ent = entryvec->vector;
509 int minfamily,
510 maxfamily,
511 minbits,
512 commonbits;
513 unsigned char *addr;
514 GistInetKey *tmp,
515 *result;
516
517 /* Determine parameters of the union. */
518 calc_inet_union_params(ent, 0, entryvec->n - 1,
519 &minfamily, &maxfamily,
520 &minbits, &commonbits);
521
522 /* If more than one family, emit family number zero. */
523 if (minfamily != maxfamily)
524 minfamily = 0;
525
526 /* Initialize address using the first key. */
527 tmp = DatumGetInetKeyP(ent[0].key);
528 addr = gk_ip_addr(tmp);
529
530 /* Construct the union value. */
531 result = build_inet_union_key(minfamily, minbits, commonbits, addr);
532
533 PG_RETURN_POINTER(result);
534}

References build_inet_union_key(), calc_inet_union_params(), DatumGetInetKeyP, gk_ip_addr, sort-test::key, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_POINTER, and GistEntryVector::vector.