📄 tsgistidx.c
字号:
BITVEC base; int4 i, len; int4 flag = 0; SignTSVector *result; MemSet((void *) base, 0, sizeof(BITVEC)); for (i = 0; i < entryvec->n; i++) { if (unionkey(base, GETENTRY(entryvec, i))) { flag = ALLISTRUE; break; } } flag |= SIGNKEY; len = CALCGTSIZE(flag, 0); result = (SignTSVector *) palloc(len); *size = len; SET_VARSIZE(result, len); result->flag = flag; if (!ISALLTRUE(result)) memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC)); PG_RETURN_POINTER(result);}Datumgtsvector_same(PG_FUNCTION_ARGS){ SignTSVector *a = (SignTSVector *) PG_GETARG_POINTER(0); SignTSVector *b = (SignTSVector *) PG_GETARG_POINTER(1); bool *result = (bool *) PG_GETARG_POINTER(2); if (ISSIGNKEY(a)) { /* then b also ISSIGNKEY */ if (ISALLTRUE(a) && ISALLTRUE(b)) *result = true; else if (ISALLTRUE(a)) *result = false; else if (ISALLTRUE(b)) *result = false; else { int4 i; BITVECP sa = GETSIGN(a), sb = GETSIGN(b); *result = true; LOOPBYTE { if (sa[i] != sb[i]) { *result = false; break; } } } } else { /* a and b ISARRKEY */ int4 lena = ARRNELEM(a), lenb = ARRNELEM(b); if (lena != lenb) *result = false; else { int4 *ptra = GETARR(a), *ptrb = GETARR(b); int4 i; *result = true; for (i = 0; i < lena; i++) if (ptra[i] != ptrb[i]) { *result = false; break; } } } PG_RETURN_POINTER(result);}static int4sizebitvec(BITVECP sign){ int4 size = 0, i; LOOPBYTE size += number_of_ones[(unsigned char) sign[i]]; return size;}static inthemdistsign(BITVECP a, BITVECP b){ int i, diff, dist = 0; LOOPBYTE { diff = (unsigned char) (a[i] ^ b[i]); dist += number_of_ones[diff]; } return dist;}static inthemdist(SignTSVector *a, SignTSVector *b){ if (ISALLTRUE(a)) { if (ISALLTRUE(b)) return 0; else return SIGLENBIT - sizebitvec(GETSIGN(b)); } else if (ISALLTRUE(b)) return SIGLENBIT - sizebitvec(GETSIGN(a)); return hemdistsign(GETSIGN(a), GETSIGN(b));}Datumgtsvector_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); SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key); SignTSVector *newval = (SignTSVector *) DatumGetPointer(newentry->key); BITVECP orig = GETSIGN(origval); *penalty = 0.0; if (ISARRKEY(newval)) { BITVEC sign; makesign(sign, newval); if (ISALLTRUE(origval)) *penalty = ((float) (SIGLENBIT - sizebitvec(sign))) / (float) (SIGLENBIT + 1); else *penalty = hemdistsign(sign, orig); } else *penalty = hemdist(origval, newval); PG_RETURN_POINTER(penalty);}typedef struct{ bool allistrue; BITVEC sign;} CACHESIGN;static voidfillcache(CACHESIGN *item, SignTSVector *key){ item->allistrue = false; if (ISARRKEY(key)) makesign(item->sign, key); else if (ISALLTRUE(key)) item->allistrue = true; else memcpy((void *) item->sign, (void *) GETSIGN(key), sizeof(BITVEC));}#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )typedef struct{ OffsetNumber pos; int4 cost;} SPLITCOST;static intcomparecost(const void *va, const void *vb){ SPLITCOST *a = (SPLITCOST *) va; SPLITCOST *b = (SPLITCOST *) vb; if (a->cost == b->cost) return 0; else return (a->cost > b->cost) ? 1 : -1;}static inthemdistcache(CACHESIGN *a, CACHESIGN *b){ if (a->allistrue) { if (b->allistrue) return 0; else return SIGLENBIT - sizebitvec(b->sign); } else if (b->allistrue) return SIGLENBIT - sizebitvec(a->sign); return hemdistsign(a->sign, b->sign);}Datumgtsvector_picksplit(PG_FUNCTION_ARGS){ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber k, j; SignTSVector *datum_l, *datum_r; BITVECP union_l, union_r; int4 size_alpha, size_beta; int4 size_waste, waste = -1; int4 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; OffsetNumber maxoff; BITVECP ptr; int i; CACHESIGN *cache; SPLITCOST *costvector; maxoff = entryvec->n - 2; nbytes = (maxoff + 2) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2)); fillcache(&cache[FirstOffsetNumber], GETENTRY(entryvec, FirstOffsetNumber)); for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { if (k == FirstOffsetNumber) fillcache(&cache[j], GETENTRY(entryvec, j)); size_waste = hemdistcache(&(cache[j]), &(cache[k])); if (size_waste > waste) { waste = size_waste; seed_1 = k; seed_2 = j; } } } left = v->spl_left; v->spl_nleft = 0; right = v->spl_right; v->spl_nright = 0; if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } /* form initial .. */ if (cache[seed_1].allistrue) { datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0)); SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0)); datum_l->flag = SIGNKEY | ALLISTRUE; } else { datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0)); SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY, 0)); datum_l->flag = SIGNKEY; memcpy((void *) GETSIGN(datum_l), (void *) cache[seed_1].sign, sizeof(BITVEC)); } if (cache[seed_2].allistrue) { datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0)); SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0)); datum_r->flag = SIGNKEY | ALLISTRUE; } else { datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0)); SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY, 0)); datum_r->flag = SIGNKEY; memcpy((void *) GETSIGN(datum_r), (void *) cache[seed_2].sign, sizeof(BITVEC)); } union_l = GETSIGN(datum_l); union_r = GETSIGN(datum_r); maxoff = OffsetNumberNext(maxoff); fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff)); /* sort before ... */ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { costvector[j - 1].pos = j; size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j])); size_beta = hemdistcache(&(cache[seed_2]), &(cache[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; } if (ISALLTRUE(datum_l) || cache[j].allistrue) { if (ISALLTRUE(datum_l) && cache[j].allistrue) size_alpha = 0; else size_alpha = SIGLENBIT - sizebitvec( (cache[j].allistrue) ? GETSIGN(datum_l) : GETSIGN(cache[j].sign) ); } else size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l)); if (ISALLTRUE(datum_r) || cache[j].allistrue) { if (ISALLTRUE(datum_r) && cache[j].allistrue) size_beta = 0; else size_beta = SIGLENBIT - sizebitvec( (cache[j].allistrue) ? GETSIGN(datum_r) : GETSIGN(cache[j].sign) ); } else size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r)); if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1)) { if (ISALLTRUE(datum_l) || cache[j].allistrue) { if (!ISALLTRUE(datum_l)) MemSet((void *) GETSIGN(datum_l), 0xff, sizeof(BITVEC)); } else { ptr = cache[j].sign; LOOPBYTE union_l[i] |= ptr[i]; } *left++ = j; v->spl_nleft++; } else { if (ISALLTRUE(datum_r) || cache[j].allistrue) { if (!ISALLTRUE(datum_r)) MemSet((void *) GETSIGN(datum_r), 0xff, sizeof(BITVEC)); } else { ptr = cache[j].sign; LOOPBYTE union_r[i] |= ptr[i]; } *right++ = j; v->spl_nright++; } } *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); PG_RETURN_POINTER(v);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -