/* *RepresentationofaGiSTINET/CIDRindexkey.Thisisnotidenticalto *INET/CIDRbecauseweneedtokeeptrackofthelengthofthecommonaddress *prefixaswellastheminimumnetmasklength.However,aslongasit *followsvarlenaheaderrules,thecoreGiSTcodewon'tknowthedifference. *Forsimplicitywealwaysuse1-byte-headervarlenaformat.
*/ typedefstruct GistInetKey
{
uint8 va_header; /* varlena header --- don't touch directly */ unsignedchar family; /* PGSQL_AF_INET, PGSQL_AF_INET6, or zero */ unsignedchar minbits; /* minimum number of bits in netmask */ unsignedchar commonbits; /* number of common prefix bits in addresses */ unsignedchar ipaddr[16]; /* up to 128 bits of common address */
} GistInetKey;
/* These require that the family field has been set: */ #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))
order = bitncmp(gk_ip_addr(key), ip_addr(query), minbits);
switch (strategy)
{ case INETSTRAT_SUB: case INETSTRAT_SUBEQ: case INETSTRAT_OVERLAPS: case INETSTRAT_SUPEQ: case INETSTRAT_SUP:
PG_RETURN_BOOL(order == 0);
case INETSTRAT_LT: case INETSTRAT_LE: if (order > 0)
PG_RETURN_BOOL(false); if (order < 0 || !GIST_LEAF(ent))
PG_RETURN_BOOL(true); break;
case INETSTRAT_EQ: if (order != 0)
PG_RETURN_BOOL(false); if (!GIST_LEAF(ent))
PG_RETURN_BOOL(true); break;
case INETSTRAT_GE: case INETSTRAT_GT: if (order < 0)
PG_RETURN_BOOL(false); if (order > 0 || !GIST_LEAF(ent))
PG_RETURN_BOOL(true); break;
case INETSTRAT_NE: if (order != 0 || !GIST_LEAF(ent))
PG_RETURN_BOOL(true); break;
}
/* *Check4:networkbitcount * *Nextstepistocomparenetmaskwidths.
*/ switch (strategy)
{ case INETSTRAT_LT: case INETSTRAT_LE: if (gk_ip_minbits(key) < ip_bits(query))
PG_RETURN_BOOL(true); if (gk_ip_minbits(key) > ip_bits(query))
PG_RETURN_BOOL(false); break;
case INETSTRAT_EQ: if (gk_ip_minbits(key) != ip_bits(query))
PG_RETURN_BOOL(false); break;
case INETSTRAT_GE: case INETSTRAT_GT: if (gk_ip_minbits(key) > ip_bits(query))
PG_RETURN_BOOL(true); if (gk_ip_minbits(key) < ip_bits(query))
PG_RETURN_BOOL(false); break;
case INETSTRAT_NE: if (gk_ip_minbits(key) != ip_bits(query))
PG_RETURN_BOOL(true); break;
}
/* *Check5:wholeaddress * *Netmaskbitcountsarethesame,socheckalltheaddressbits.
*/
order = bitncmp(gk_ip_addr(key), ip_addr(query), gk_ip_maxbits(key));
switch (strategy)
{ case INETSTRAT_LT:
PG_RETURN_BOOL(order < 0);
/* *CalculateparametersoftheunionofsomeGistInetKeys. * *Examinethekeysinelementsm..ninclusiveoftheGISTENTRYarray, *andcomputetheseoutputparameters: **minfamily_p=minimumIPaddressfamilynumber **maxfamily_p=maximumIPaddressfamilynumber **minbits_p=minimumnetmaskwidth **commonbits_p=numberofleadingbitsincommonamongtheaddresses * *minbitsandcommonbitsareforcedtozeroifthere'smorethanone *addressfamily.
*/ staticvoid
calc_inet_union_params(GISTENTRY *ent, int m, int n, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
{ int minfamily,
maxfamily,
minbits,
commonbits; unsignedchar *addr;
GistInetKey *tmp; int i;
/* Must be at least one key. */
Assert(m <= n);
/* Initialize variables using the first key. */
tmp = DatumGetInetKeyP(ent[m].key);
minfamily = maxfamily = gk_ip_family(tmp);
minbits = gk_ip_minbits(tmp);
commonbits = gk_ip_commonbits(tmp);
addr = gk_ip_addr(tmp);
/* Scan remaining keys. */ for (i = m + 1; i <= n; i++)
{
tmp = DatumGetInetKeyP(ent[i].key);
/* Determine range of family numbers */ if (minfamily > gk_ip_family(tmp))
minfamily = gk_ip_family(tmp); if (maxfamily < gk_ip_family(tmp))
maxfamily = gk_ip_family(tmp);
/* Find minimum number of bits in common */ if (commonbits > gk_ip_commonbits(tmp))
commonbits = gk_ip_commonbits(tmp); if (commonbits > 0)
commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
}
/* Force minbits/commonbits to zero if more than one family. */ if (minfamily != maxfamily)
minbits = commonbits = 0;
/* *Sameasabove,buttheGISTENTRYelementstoexaminearethosewith *indiceslistedintheoffsets[]array.
*/ staticvoid
calc_inet_union_params_indexed(GISTENTRY *ent,
OffsetNumber *offsets, int noffsets, int *minfamily_p, int *maxfamily_p, int *minbits_p, int *commonbits_p)
{ int minfamily,
maxfamily,
minbits,
commonbits; unsignedchar *addr;
GistInetKey *tmp; int i;
/* Must be at least one key. */
Assert(noffsets > 0);
/* Initialize variables using the first key. */
tmp = DatumGetInetKeyP(ent[offsets[0]].key);
minfamily = maxfamily = gk_ip_family(tmp);
minbits = gk_ip_minbits(tmp);
commonbits = gk_ip_commonbits(tmp);
addr = gk_ip_addr(tmp);
/* Scan remaining keys. */ for (i = 1; i < noffsets; i++)
{
tmp = DatumGetInetKeyP(ent[offsets[i]].key);
/* Determine range of family numbers */ if (minfamily > gk_ip_family(tmp))
minfamily = gk_ip_family(tmp); if (maxfamily < gk_ip_family(tmp))
maxfamily = gk_ip_family(tmp);
/* Find minimum number of bits in common */ if (commonbits > gk_ip_commonbits(tmp))
commonbits = gk_ip_commonbits(tmp); if (commonbits > 0)
commonbits = bitncommon(addr, gk_ip_addr(tmp), commonbits);
}
/* Force minbits/commonbits to zero if more than one family. */ if (minfamily != maxfamily)
minbits = commonbits = 0;
/* Determine parameters of the union of all the inputs. */
calc_inet_union_params(ent, FirstOffsetNumber, maxoff,
&minfamily, &maxfamily,
&minbits, &commonbits);
if (minfamily != maxfamily)
{ /* Multiple families, so split by family. */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{ /* *Ifthere'smorethan2families,allbutmaxfamilygointothe *leftunion.Thiscouldonlyhappeniftheinputsincludesome *IPv4,someIPv6,andsomealready-multiple-familyunions.
*/
tmp = DatumGetInetKeyP(ent[i].key); if (gk_ip_family(tmp) != maxfamily)
left[splitvec->spl_nleft++] = i; else
right[splitvec->spl_nright++] = i;
}
} else
{ /* *Splitonthenextbitafterthecommonbits.Ifthatyieldsa *trivialsplit,trythenextbitpositiontotheright.Repeattill *success;orifwerunoutofbits,doanarbitrary50-50split.
*/ int maxbits = ip_family_maxbits(minfamily);
while (commonbits < maxbits)
{ /* Split using the commonbits'th bit position. */ int bitbyte = commonbits / 8; int bitmask = 0x80 >> (commonbits % 8);
splitvec->spl_nleft = splitvec->spl_nright = 0;
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
tmp = DatumGetInetKeyP(ent[i].key);
addr = gk_ip_addr(tmp); if ((addr[bitbyte] & bitmask) == 0)
left[splitvec->spl_nleft++] = i; else
right[splitvec->spl_nright++] = i;
}
if (commonbits >= maxbits)
{ /* Failed ... do a 50-50 split. */
splitvec->spl_nleft = splitvec->spl_nright = 0;
for (i = FirstOffsetNumber; i <= maxoff / 2; i = OffsetNumberNext(i))
{
left[splitvec->spl_nleft++] = i;
} for (; i <= maxoff; i = OffsetNumberNext(i))
{
right[splitvec->spl_nright++] = i;
}
}
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.19Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.