Datum gtsquery_penalty(PG_FUNCTION_ARGS) { TSQuerySign *origval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key); TSQuerySign *newval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *penalty = (float *) PG_GETARG_POINTER(2); *penalty = hemdist(*origval, *newval); PG_RETURN_POINTER(penalty); }
Datum gtsquery_penalty(PG_FUNCTION_ARGS) { TSQuerySign origval = DatumGetTSQuerySign(((GISTENTRY *) PG_GETARG_POINTER(0))->key); TSQuerySign newval = DatumGetTSQuerySign(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *penalty = (float *) PG_GETARG_POINTER(2); *penalty = hemdist(origval, newval); PG_RETURN_POINTER(penalty); }
Datum gmol_penalty(PG_FUNCTION_ARGS) { GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); float *penalty = (float *) PG_GETARG_POINTER(2); bytea *origval = (bytea *) DatumGetPointer(origentry->key); bytea *newval = (bytea *) DatumGetPointer(newentry->key); *penalty = (float)hemdist(origval, newval); PG_RETURN_POINTER(penalty); }
Datum gtsquery_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber maxoff = entryvec->n - 2; OffsetNumber k, j; TSQuerySign *datum_l, *datum_r; int4 size_alpha, size_beta; int4 size_waste, waste = -1; int4 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; SPLITCOST *costvector; nbytes = (maxoff + 2) * sizeof(OffsetNumber); left = v->spl_left = (OffsetNumber *) palloc(nbytes); right = v->spl_right = (OffsetNumber *) palloc(nbytes); v->spl_nleft = v->spl_nright = 0; for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { size_waste = hemdist(*GETENTRY(entryvec, j), *GETENTRY(entryvec, k)); if (size_waste > waste) { waste = size_waste; seed_1 = k; seed_2 = j; } } if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } datum_l = (TSQuerySign *) palloc(sizeof(TSQuerySign)); *datum_l = *GETENTRY(entryvec, seed_1); datum_r = (TSQuerySign *) palloc(sizeof(TSQuerySign)); *datum_r = *GETENTRY(entryvec, seed_2); maxoff = OffsetNumberNext(maxoff); costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { costvector[j - 1].pos = j; size_alpha = hemdist(*GETENTRY(entryvec, seed_1), *GETENTRY(entryvec, j)); size_beta = hemdist(*GETENTRY(entryvec, seed_2), *GETENTRY(entryvec, j)); costvector[j - 1].cost = abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); for (k = 0; k < maxoff; k++) { j = costvector[k].pos; if (j == seed_1) { *left++ = j; v->spl_nleft++; continue; } else if (j == seed_2) { *right++ = j; v->spl_nright++; continue; } size_alpha = hemdist(*datum_l, *GETENTRY(entryvec, j)); size_beta = hemdist(*datum_r, *GETENTRY(entryvec, j)); if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05)) { *datum_l |= *GETENTRY(entryvec, j); *left++ = j; v->spl_nleft++; } else { *datum_r |= *GETENTRY(entryvec, j); *right++ = j; v->spl_nright++; } } *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); PG_RETURN_POINTER(v); }
Datum gmol_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber k, j; bytea *datum_l, *datum_r; int32 size_alpha, size_beta; int32 size_waste, waste = -1; int32 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; OffsetNumber maxoff; int i, signlen = 0; SPLITCOST *costvector; maxoff = entryvec->n - 1; nbytes = (maxoff + 2) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { if (signlen == 0) { signlen = SIGLEN(GETENTRY(entryvec, k)); } for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { size_waste = hemdist(GETENTRY(entryvec, j), GETENTRY(entryvec, k)); if (size_waste > waste) { waste = size_waste; seed_1 = k; seed_2 = j; } } } if (signlen == 0) { signlen = SIGLEN(GETENTRY(entryvec, maxoff)); } left = v->spl_left; v->spl_nleft = 0; right = v->spl_right; v->spl_nright = 0; if (signlen == 0 || waste == 0) { /* all entries a alltrue or all the same */ for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k)) { if (k <= (maxoff - FirstOffsetNumber + 1) / 2) { v->spl_left[v->spl_nleft] = k; v->spl_nleft++; } else { v->spl_right[v->spl_nright] = k; v->spl_nright++; } } signlen = VARSIZE(GETENTRY(entryvec, FirstOffsetNumber)); datum_l = palloc(signlen); memcpy(datum_l, GETENTRY(entryvec, FirstOffsetNumber), signlen); v->spl_ldatum = PointerGetDatum(datum_l); datum_r = palloc(signlen); memcpy(datum_r, GETENTRY(entryvec, FirstOffsetNumber), signlen); v->spl_rdatum = PointerGetDatum(datum_r); Assert( v->spl_nleft + v->spl_nright == maxoff ); PG_RETURN_POINTER(v); } if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } /* form initial .. */ if (ISALLTRUE(GETENTRY(entryvec, seed_1))) { datum_l = palloc(VARHDRSZ); SET_VARSIZE(datum_l, VARHDRSZ); } else { datum_l = palloc(signlen + VARHDRSZ); memcpy(datum_l , GETENTRY(entryvec, seed_1) , signlen + VARHDRSZ); } if (ISALLTRUE(GETENTRY(entryvec, seed_2))) { datum_r = palloc(VARHDRSZ); SET_VARSIZE(datum_r, VARHDRSZ); } else { datum_r = palloc(signlen + VARHDRSZ); memcpy(datum_r , GETENTRY(entryvec, seed_2) , signlen + VARHDRSZ); } /* sort before ... */ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { costvector[j - 1].pos = j; size_alpha = hemdist(datum_l, GETENTRY(entryvec, j)); size_beta = hemdist(datum_r, GETENTRY(entryvec, j)); costvector[j - 1].cost = Abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); for (k = 0; k < maxoff; k++) { j = costvector[k].pos; if (j == seed_1) { *left++ = j; v->spl_nleft++; continue; } else if (j == seed_2) { *right++ = j; v->spl_nright++; continue; } size_alpha = hemdist(GETENTRY(entryvec, j), datum_l); size_beta = hemdist(GETENTRY(entryvec, j), datum_r); if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1)) { if (!ISALLTRUE(datum_l)) { if (ISALLTRUE(GETENTRY(entryvec, j))) { datum_l = palloc(VARHDRSZ); SET_VARSIZE(datum_l, VARHDRSZ); } else { unsigned char *as = (unsigned char *)VARDATA(datum_l), *bs = (unsigned char *)VARDATA(GETENTRY(entryvec, j)); for (i=0;i<signlen;i++) { as[i] |= bs[i]; } } } *left++ = j; v->spl_nleft++; } else { if (!ISALLTRUE(datum_r)) { if (ISALLTRUE(GETENTRY(entryvec, j))) { datum_r = palloc(VARHDRSZ); SET_VARSIZE(datum_r, VARHDRSZ); } else { unsigned char *as = (unsigned char *)VARDATA(datum_r), *bs = (unsigned char *)VARDATA(GETENTRY(entryvec, j)); for (i=0;i<signlen;i++) { as[i] |= bs[i]; } } } *right++ = j; v->spl_nright++; } } *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); Assert( v->spl_nleft + v->spl_nright == maxoff ); PG_RETURN_POINTER(v); }