Datum
g_int_union(PG_FUNCTION_ARGS)
{
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1);
int32 i,
*ptr;
ArrayType *res; int totlen = 0;
for (i = 0; i < entryvec->n; i++)
{
ArrayType *ent = GETENTRY(entryvec, i);
CHECKARRVALID(ent);
totlen += ARRNELEMS(ent);
}
res = new_intArrayType(totlen);
ptr = ARRPTR(res);
for (i = 0; i < entryvec->n; i++)
{
ArrayType *ent = GETENTRY(entryvec, i); int nel;
nel = ARRNELEMS(ent);
memcpy(ptr, ARRPTR(ent), nel * sizeof(int32));
ptr += nel;
}
QSORT(res, 1);
res = _int_unique(res);
*size = VARSIZE(res);
PG_RETURN_POINTER(res);
}
/* **GiSTCompressandDecompressmethods
*/
Datum
g_int_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
ArrayType *r; int num_ranges = G_INT_GET_NUMRANGES(); int len,
lenr; int *dr; int i,
j,
cand;
int64 min;
if (entry->leafkey)
{
r = DatumGetArrayTypePCopy(entry->key);
CHECKARRVALID(r);
PREPAREARR(r);
if (ARRNELEMS(r) >= 2 * num_ranges)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("input array is too big (%d maximum allowed, %d current), use gist__intbig_ops opclass instead", 2 * num_ranges - 1, ARRNELEMS(r))));
r = DatumGetArrayTypeP(entry->key);
CHECKARRVALID(r); if (ARRISEMPTY(r))
{ if (r != (ArrayType *) DatumGetPointer(entry->key))
pfree(r);
PG_RETURN_POINTER(entry);
}
if ((len = ARRNELEMS(r)) >= 2 * num_ranges)
{ /* compress */ if (r == (ArrayType *) DatumGetPointer(entry->key))
r = DatumGetArrayTypePCopy(entry->key);
r = resize_intArrayType(r, 2 * (len));
dr = ARRPTR(r);
/* *"len"atthispointisthenumberofrangeswewillconstruct. *"lenr"isthenumberofrangeswemusteventuallyremoveby *merging,wemustbecarefultoremovenomorethanthisnumber.
*/
lenr = len - num_ranges;
/* *Initiallyassumewecanmergeconsecutiveintsintoarange.butwe *mustcounteveryvalueremovedandstopwhenlenrrunsout
*/ for (j = i = len - 1; i > 0 && lenr > 0; i--, j--)
{ int r_end = dr[i]; int r_start = r_end;
while (i > 0 && lenr > 0 && dr[i - 1] == r_start - 1)
--r_start, --i, --lenr;
dr[2 * j] = r_start;
dr[2 * j + 1] = r_end;
} /* just copy the rest, if any, as trivial ranges */ for (; i >= 0; i--, j--)
dr[2 * j] = dr[2 * j + 1] = dr[i];
Datum
g_int_decompress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
ArrayType *r; int num_ranges = G_INT_GET_NUMRANGES(); int *dr,
lenr;
ArrayType *in; int lenin; int *din; int i;
in = DatumGetArrayTypeP(entry->key);
CHECKARRVALID(in); if (ARRISEMPTY(in))
{ if (in != (ArrayType *) DatumGetPointer(entry->key))
{
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(in),
entry->rel, entry->page, entry->offset, false);
PG_RETURN_POINTER(retval);
}
PG_RETURN_POINTER(entry);
}
lenin = ARRNELEMS(in);
if (lenin < 2 * num_ranges)
{ /* not compressed value */ if (in != (ArrayType *) DatumGetPointer(entry->key))
{
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(in),
entry->rel, entry->page, entry->offset, false);
din = ARRPTR(in);
lenr = internal_size(din, lenin); if (lenr < 0 || lenr > MAXNUMELTS)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("compressed array is too big, recreate index using gist__intbig_ops opclass instead")));
r = new_intArrayType(lenr);
dr = ARRPTR(r);
for (i = 0; i < lenin; i += 2)
{ /* use int64 for j in case din[i + 1] is INT_MAX */ for (int64 j = din[i]; j <= din[i + 1]; j++) if ((!i) || *(dr - 1) != j)
*dr++ = (int) j;
}
if (in != (ArrayType *) DatumGetPointer(entry->key))
pfree(in);
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->offset, false);
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.