PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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.

104 : 4)

◆ 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

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

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 473 of file network_gist.c.

475{
476 GistInetKey *result;
477
478 /* Make sure any unused bits are zeroed. */
479 result = palloc0_object(GistInetKey);
480
481 gk_ip_family(result) = family;
482 gk_ip_minbits(result) = minbits;
483 gk_ip_commonbits(result) = commonbits;
484
485 /* Clone appropriate bytes of the address. */
486 if (commonbits > 0)
487 memcpy(gk_ip_addr(result), addr, (commonbits + 7) / 8);
488
489 /* Clean any unwanted bits in the last partial byte. */
490 if (commonbits % 8 != 0)
491 gk_ip_addr(result)[commonbits / 8] &= ~(0xFF >> (commonbits % 8));
492
493 /* Set varlena header correctly. */
494 SET_GK_VARSIZE(result);
495
496 return result;
497}
#define palloc0_object(type)
Definition fe_memutils.h:75
#define gk_ip_commonbits(gkptr)
#define gk_ip_family(gkptr)
#define gk_ip_addr(gkptr)
#define SET_GK_VARSIZE(dst)
#define gk_ip_minbits(gkptr)
static int fb(int x)

References fb(), gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, palloc0_object, 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 346 of file network_gist.c.

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

References Assert, bitncommon(), DatumGetInetKeyP, fb(), gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, and i.

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 408 of file network_gist.c.

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

References Assert, bitncommon(), DatumGetInetKeyP, fb(), gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, and i.

Referenced by inet_gist_picksplit().

◆ inet_gist_compress()

Datum inet_gist_compress ( PG_FUNCTION_ARGS  )

Definition at line 543 of file network_gist.c.

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

References Assert, bitncmp(), DatumGetInetKeyP, elog, ERROR, fb(), 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, Min, PG_GETARG_INET_PP, PG_GETARG_OID, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

◆ inet_gist_fetch()

Datum inet_gist_fetch ( PG_FUNCTION_ARGS  )

Definition at line 591 of file network_gist.c.

592{
593 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
595 GISTENTRY *retval;
596 inet *dst;
597
599
600 ip_family(dst) = gk_ip_family(key);
601 ip_bits(dst) = gk_ip_minbits(key);
604
605 retval = palloc_object(GISTENTRY);
606 gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page,
607 entry->offset, false);
608
609 PG_RETURN_POINTER(retval);
610}
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, fb(), gistentryinit, gk_ip_addr, gk_ip_family, gk_ip_minbits, InetPGetDatum(), ip_addr, ip_addrsize, ip_bits, ip_family, GISTENTRY::key, GISTENTRY::offset, GISTENTRY::page, palloc0_object, palloc_object, 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 621 of file network_gist.c.

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

References bitncommon(), DatumGetInetKeyP, fb(), gk_ip_addr, gk_ip_commonbits, gk_ip_family, gk_ip_minbits, Min, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ inet_gist_picksplit()

Datum inet_gist_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 664 of file network_gist.c.

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

References build_inet_union_key(), calc_inet_union_params(), calc_inet_union_params_indexed(), DatumGetInetKeyP, fb(), FirstOffsetNumber, gk_ip_addr, gk_ip_family, i, ip_family_maxbits, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, and PointerGetDatum().

◆ inet_gist_same()

Datum inet_gist_same ( PG_FUNCTION_ARGS  )

Definition at line 798 of file network_gist.c.

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

References DatumGetInetKeyP, fb(), 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 506 of file network_gist.c.

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

References build_inet_union_key(), calc_inet_union_params(), DatumGetInetKeyP, fb(), gk_ip_addr, PG_GETARG_POINTER, and PG_RETURN_POINTER.