diff options
author | Bruce Momjian | 2003-06-11 18:44:15 +0000 |
---|---|---|
committer | Bruce Momjian | 2003-06-11 18:44:15 +0000 |
commit | 47d5c3d5e713439e5e0cfe3ad751786388905242 (patch) | |
tree | d7a8b2ea4fbf07b8cf6a4a2ffcf359b4b8f979ac /contrib/ltree/_ltree_gist.c | |
parent | d2e028b1b03218707960b44843af94e311e8f368 (diff) |
Changes:
1 intarray: bugfix for int[]-int[] operation
2 intarray: split _int.c to several files (_int.c now is unused)
3 ntarray (gist__intbig_ops opclass): use special type for index storage
4 ltree (gist__ltree_ops opclass), intarray (gist__intbig_ops): optimize
GiST's
penalty and picksplit interface functions, now use Hemming distance.
Teodor Sigaev
Diffstat (limited to 'contrib/ltree/_ltree_gist.c')
-rw-r--r-- | contrib/ltree/_ltree_gist.c | 234 |
1 files changed, 59 insertions, 175 deletions
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c index 1791f5bd8d4..ec20067230e 100644 --- a/contrib/ltree/_ltree_gist.c +++ b/contrib/ltree/_ltree_gist.c @@ -211,35 +211,39 @@ sizebitvec(BITVECP sign) return size; } +static int +hemdistsign(BITVECP a, BITVECP b) { + int i,dist=0; + + ALOOPBIT( + if ( GETBIT(a,i) != GETBIT(b,i) ) + dist++; + ); + return dist; +} + +static int +hemdist(ltree_gist *a, ltree_gist *b) { + if ( LTG_ISALLTRUE(a) ) { + if (LTG_ISALLTRUE(b)) + return 0; + else + return ASIGLENBIT-sizebitvec(LTG_SIGN(b)); + } else if (LTG_ISALLTRUE(b)) + return ASIGLENBIT-sizebitvec(LTG_SIGN(a)); + + return hemdistsign( LTG_SIGN(a), LTG_SIGN(b) ); +} + + Datum _ltree_penalty(PG_FUNCTION_ARGS) { ltree_gist *origval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key); ltree_gist *newval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *penalty = (float *) PG_GETARG_POINTER(2); - BITVECP orig = LTG_SIGN(origval); - if (LTG_ISALLTRUE(origval)) - { - *penalty = 0.1; - PG_RETURN_POINTER(penalty); - } - - if (LTG_ISALLTRUE(newval)) - *penalty = (float) (ASIGLENBIT - sizebitvec(orig)); - else - { - unsigned char valtmp; - BITVECP nval = LTG_SIGN(newval); - int4 i, - unionsize = 0; - - ALOOPBYTE( - valtmp = nval[i] | orig[i]; - unionsize += SUMBIT(valtmp) - SUMBIT(orig[i]); - ); - *penalty = (float) unionsize; - } + *penalty=hemdist(origval,newval); PG_RETURN_POINTER(penalty); } @@ -264,28 +268,19 @@ _ltree_picksplit(PG_FUNCTION_ARGS) j; ltree_gist *datum_l, *datum_r; - ABITVEC union_l, + BITVECP union_l, union_r; - bool firsttime = true; - int4 size_alpha, - size_beta, - sizeu, - sizei; + int4 size_alpha, size_beta; int4 size_waste, - waste = 0.0; - int4 size_l, - size_r; + waste = -1; int4 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; OffsetNumber maxoff; - BITVECP ptra, - ptrb, - ptrc; + BITVECP ptr; int i; - unsigned char valtmp; SPLITCOST *costvector; ltree_gist *_k, *_j; @@ -295,57 +290,14 @@ _ltree_picksplit(PG_FUNCTION_ARGS) v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); - for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) - { + for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { _k = GETENTRY(entryvec, k); - for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) - { - _j = GETENTRY(entryvec, j); - if (LTG_ISALLTRUE(_k) || LTG_ISALLTRUE(_j)) - { - sizeu = ASIGLENBIT; - if (LTG_ISALLTRUE(_k) && LTG_ISALLTRUE(_j)) - sizei = ASIGLENBIT; - else - sizei = (LTG_ISALLTRUE(_k)) ? - sizebitvec(LTG_SIGN(_j)) : sizebitvec(LTG_SIGN(_k)); - } - else - { - sizeu = sizei = 0; - ptra = LTG_SIGN(_j); - ptrb = LTG_SIGN(_k); - /* critical section for bench !!! */ - -#define COUNT(pos) do { \ - if ( GETBITBYTE(*(char*)ptra,pos) ) { \ - sizeu++; \ - if ( GETBITBYTE(*(char*)ptrb, pos) ) \ - sizei++; \ - } else if ( GETBITBYTE(*(char*)ptrb, pos) ) \ - sizeu++; \ -} while(0) - - ALOOPBYTE( - COUNT(0); - COUNT(1); - COUNT(2); - COUNT(3); - COUNT(4); - COUNT(5); - COUNT(6); - COUNT(7); - ptra = (BITVECP) (((char *) ptra) + 1); - ptrb = (BITVECP) (((char *) ptrb) + 1); - ); - } - size_waste = sizeu - sizei; - if (size_waste > waste || firsttime) - { + for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { + size_waste=hemdist(_k, GETENTRY(entryvec, j)); + if (size_waste > waste ) { waste = size_waste; seed_1 = k; seed_2 = j; - firsttime = false; } } } @@ -367,7 +319,6 @@ _ltree_picksplit(PG_FUNCTION_ARGS) datum_l = (ltree_gist *) palloc(LTG_HDRSIZE); datum_l->len = LTG_HDRSIZE; datum_l->flag = LTG_ALLTRUE; - size_l = ASIGLENBIT; } else { @@ -375,14 +326,12 @@ _ltree_picksplit(PG_FUNCTION_ARGS) datum_l->len = LTG_HDRSIZE + ASIGLEN; datum_l->flag = 0; memcpy((void *) LTG_SIGN(datum_l), (void *) LTG_SIGN(GETENTRY(entryvec, seed_1)), sizeof(ABITVEC)); - size_l = sizebitvec(LTG_SIGN(datum_l)); } if (LTG_ISALLTRUE(GETENTRY(entryvec, seed_2))) { datum_r = (ltree_gist *) palloc(LTG_HDRSIZE); datum_r->len = LTG_HDRSIZE; datum_r->flag = LTG_ALLTRUE; - size_r = ASIGLENBIT; } else { @@ -390,7 +339,6 @@ _ltree_picksplit(PG_FUNCTION_ARGS) datum_r->len = LTG_HDRSIZE + ASIGLEN; datum_r->flag = 0; memcpy((void *) LTG_SIGN(datum_r), (void *) LTG_SIGN(GETENTRY(entryvec, seed_2)), sizeof(ABITVEC)); - size_r = sizebitvec(LTG_SIGN(datum_r)); } maxoff = OffsetNumberNext(maxoff); @@ -400,55 +348,18 @@ _ltree_picksplit(PG_FUNCTION_ARGS) { costvector[j - 1].pos = j; _j = GETENTRY(entryvec, j); - if (LTG_ISALLTRUE(_j)) - { - size_alpha = ASIGLENBIT - size_l; - size_beta = ASIGLENBIT - size_r; - } - else - { - ptra = LTG_SIGN(datum_l); - ptrb = LTG_SIGN(datum_r); - ptrc = LTG_SIGN(_j); - size_beta = size_alpha = 0; - if (LTG_ISALLTRUE(datum_l)) - { - if (!LTG_ISALLTRUE(datum_r)) - { - ALOOPBIT( - if (GETBIT(ptrc, i) && !GETBIT(ptrb, i)) - size_beta++; - ); - } - } - else if (LTG_ISALLTRUE(datum_r)) - { - if (!LTG_ISALLTRUE(datum_l)) - { - ALOOPBIT( - if (GETBIT(ptrc, i) && !GETBIT(ptra, i)) - size_alpha++; - ); - } - } - else - { - ALOOPBIT( - if (GETBIT(ptrc, i) && !GETBIT(ptra, i)) - size_alpha++; - if (GETBIT(ptrc, i) && !GETBIT(ptrb, i)) - size_beta++; - ); - } - } + size_alpha = hemdist(datum_l,_j); + size_beta = hemdist(datum_r,_j); costvector[j - 1].cost = abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); + union_l=LTG_SIGN(datum_l); + union_r=LTG_SIGN(datum_r); + for (k = 0; k < maxoff; k++) { j = costvector[k].pos; - _j = GETENTRY(entryvec, j); if (j == seed_1) { *left++ = j; @@ -461,62 +372,35 @@ _ltree_picksplit(PG_FUNCTION_ARGS) v->spl_nright++; continue; } + _j = GETENTRY(entryvec, j); + size_alpha = hemdist(datum_l,_j); + size_beta = hemdist(datum_r,_j); - if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j)) - size_alpha = ASIGLENBIT; - else - { - ptra = LTG_SIGN(_j); - ptrb = LTG_SIGN(datum_l); - size_alpha = 0; - ALOOPBYTE( - valtmp = union_l[i] = ptra[i] | ptrb[i]; - size_alpha += SUMBIT(valtmp); - ); - } - - if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j)) - size_beta = ASIGLENBIT; - else - { - ptra = LTG_SIGN(_j); - ptrb = LTG_SIGN(datum_r); - size_beta = 0; - ALOOPBYTE( - valtmp = union_r[i] = ptra[i] | ptrb[i]; - size_beta += SUMBIT(valtmp); - ); - } - - if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.00001)) + if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001)) { - if (!LTG_ISALLTRUE(datum_l)) - { - if (size_alpha == ASIGLENBIT) - { - if (size_alpha != size_l) - MemSet((void *) LTG_SIGN(datum_l), 0xff, sizeof(ABITVEC)); - } - else - memcpy((void *) LTG_SIGN(datum_l), (void *) union_l, sizeof(ABITVEC)); + if (LTG_ISALLTRUE(datum_l) || LTG_ISALLTRUE(_j) ) { + if (!LTG_ISALLTRUE(datum_l)) + MemSet((void *) union_l, 0xff, sizeof(ABITVEC)); + } else { + ptr=LTG_SIGN(_j); + ALOOPBYTE( + union_l[i] |= ptr[i]; + ); } - size_l = size_alpha; *left++ = j; v->spl_nleft++; } else { - if (!LTG_ISALLTRUE(datum_r)) - { - if (size_beta == ASIGLENBIT) - { - if (size_beta != size_r) - MemSet((void *) LTG_SIGN(datum_r), 0xff, sizeof(ABITVEC)); - } - else - memcpy((void *) LTG_SIGN(datum_r), (void *) union_r, sizeof(ABITVEC)); + if (LTG_ISALLTRUE(datum_r) || LTG_ISALLTRUE(_j) ) { + if (!LTG_ISALLTRUE(datum_r)) + MemSet((void *) union_r, 0xff, sizeof(ABITVEC)); + } else { + ptr=LTG_SIGN(_j); + ALOOPBYTE( + union_r[i] |= ptr[i]; + ); } - size_r = size_beta; *right++ = j; v->spl_nright++; } |