static int soergeldist(bytea *a, bytea *b) { if (ISALLTRUE(a)) { if (ISALLTRUE(b)) return 0; else return SIGLENBIT(b) - sizebitvec(b); } else if (ISALLTRUE(b)) { return SIGLENBIT(a) - sizebitvec(a); } return soergeldistsign(a, b); }
static int hemdist(TSQuerySign a, TSQuerySign b) { TSQuerySign res = a ^ b; return sizebitvec(res); }
static bool rdkit_consistent(GISTENTRY *entry, StrategyNumber strategy, bytea *key, bytea *query) { double nCommon, nQuery, nKey = 0.0; if (ISALLTRUE(query)) elog(ERROR, "Query malformed"); /* * Counts basic numbers, but don't count nKey on inner * page (see comments below) */ nQuery = (double)sizebitvec(query); if (ISALLTRUE(key)) { if (GIST_LEAF(entry)) nKey = (double)SIGLENBIT(query); nCommon = nQuery; } else { int i, cnt = 0; unsigned char *pk = (unsigned char*)VARDATA(key); unsigned char *pq = (unsigned char*)VARDATA(query); if (SIGLEN(key) != SIGLEN(query)) elog(ERROR, "All fingerprints should be the same length"); #ifndef USE_BUILTIN_POPCOUNT for(i=0;i<SIGLEN(key);i++) cnt += number_of_ones[ pk[i] & pq[i] ]; #else unsigned eidx=SIGLEN(key)/sizeof(unsigned int); for(i=0;i<eidx;++i){ cnt += __builtin_popcount(((unsigned int *)pk)[i] & ((unsigned int *)pq)[i]); } for(i=eidx*sizeof(unsigned);i<SIGLEN(key);++i){ cnt += number_of_ones[ pk[i] & pq[i] ]; } #endif nCommon = (double)cnt; if (GIST_LEAF(entry)) nKey = (double)sizebitvec(key); } return calcConsistency(GIST_LEAF(entry), strategy, nCommon, nCommon, nKey, nQuery); }
Datum gsfp_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool *recheck = (bool *) PG_GETARG_POINTER(4); bytea *key = (bytea*)DatumGetPointer(entry->key); bytea *query; MolSparseFingerPrint data; fcinfo->flinfo->fn_extra = SearchSparseFPCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(1), NULL, &data, &query); *recheck = true; /* we use signature, so it's needed to recheck */ if (ISALLTRUE(key) && !GIST_LEAF(entry)) { PG_RETURN_BOOL(true); } else { int sum, overlapSum, overlapN; countOverlapValues( (ISALLTRUE(key)) ? NULL : key, data, NUMBITS, &sum, &overlapSum, &overlapN ); PG_RETURN_BOOL( calcConsistency( GIST_LEAF(entry), strategy, overlapSum, /* nCommonUp */ overlapN, /* nCommonDown */ (ISALLTRUE(key)) ? NUMBITS : sizebitvec(key), /* nKey */ sum /* nQuery */ ) ); } }
Datum gtsvectorout(PG_FUNCTION_ARGS) { SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0))); char *outbuf; if (outbuf_maxlen == 0) outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1; outbuf = palloc(outbuf_maxlen); if (ISARRKEY(key)) sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key)); else { int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT : sizebitvec(GETSIGN(key)); sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue); } PG_FREE_IF_COPY(key, 0); PG_RETURN_POINTER(outbuf); }
Datum gbfp_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); // bytea *query = PG_GETARG_DATA_TYPE_P(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bytea *key = (bytea*)DatumGetPointer(entry->key); bytea *query; double nCommon, nCommonUp, nCommonDown, nQuery, distance; double nKey = 0.0; fcinfo->flinfo->fn_extra = SearchBitmapFPCache( fcinfo->flinfo->fn_extra, fcinfo->flinfo->fn_mcxt, PG_GETARG_DATUM(1), NULL, NULL,&query); if (ISALLTRUE(query)) elog(ERROR, "Query malformed"); /* * Counts basic numbers, but don't count nKey on inner * page (see comments below) */ nQuery = (double)sizebitvec(query); if (ISALLTRUE(key)) { if (GIST_LEAF(entry)) nKey = (double)SIGLENBIT(query); nCommon = nQuery; } else { int i, cnt = 0; unsigned char *pk = (unsigned char*)VARDATA(key), *pq = (unsigned char*)VARDATA(query); if (SIGLEN(key) != SIGLEN(query)) elog(ERROR, "All fingerprints should be the same length"); #ifndef USE_BUILTIN_POPCOUNT for(i=0;i<SIGLEN(key);i++) cnt += number_of_ones[ pk[i] & pq[i] ]; #else unsigned eidx=SIGLEN(key)/sizeof(unsigned int); for(i=0;i<SIGLEN(key)/sizeof(unsigned int);++i){ cnt += __builtin_popcount(((unsigned int *)pk)[i] & ((unsigned int *)pq)[i]); } for(i=eidx*sizeof(unsigned);i<SIGLEN(key);++i){ cnt += number_of_ones[ pk[i] & pq[i] ]; } #endif nCommon = (double)cnt; if (GIST_LEAF(entry)) nKey = (double)sizebitvec(key); } nCommonUp = nCommon; nCommonDown = nCommon; switch(strategy) { case RDKitOrderByTanimotoStrategy: /* * Nsame / (Na + Nb - Nsame) */ if (GIST_LEAF(entry)) { distance = nCommonUp / (nKey + nQuery - nCommonUp); } else { distance = nCommonUp / nQuery; } break; case RDKitOrderByDiceStrategy: /* * 2 * Nsame / (Na + Nb) */ if (GIST_LEAF(entry)) { distance = 2.0 * nCommonUp / (nKey + nQuery); } else { distance = 2.0 * nCommonUp / (nCommonDown + nQuery); } break; default: elog(ERROR,"Unknown strategy: %d", strategy); } PG_RETURN_FLOAT8(1.0 - distance); }