/* * Add bits of given value to the signature. */ void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno) { uint32 hashVal; int nBit, j; /* * init generator with "column's" number to get "hashed" seed for new * value. We don't want to map the same numbers from different columns * into the same bits! */ mySrand(attno); /* * Init hash sequence to map our value into bits. the same values in * different columns will be mapped into different bits because of step * above */ hashVal = DatumGetInt32(FunctionCall1Coll(&state->hashFn[attno], state->collations[attno], value)); mySrand(hashVal ^ myRand()); for (j = 0; j < state->opts.bitSize[attno]; j++) { /* prevent multiple evaluation in SETBIT macro */ nBit = myRand() % (state->opts.bloomLength * SIGNWORDBITS); SETBIT(sign, nBit); } }
/* * initialize a GiST entry with a decompressed version of key */ void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, Datum k, Relation r, Page pg, OffsetNumber o, bool l, bool isNull) { if (!isNull) { GISTENTRY *dep; gistentryinit(*e, k, r, pg, o, l); /* there may not be a decompress function in opclass */ if (!OidIsValid(giststate->decompressFn[nkey].fn_oid)) return; dep = (GISTENTRY *) DatumGetPointer(FunctionCall1Coll(&giststate->decompressFn[nkey], giststate->supportCollation[nkey], PointerGetDatum(e))); /* decompressFn may just return the given pointer */ if (dep != e) gistentryinit(*e, dep->key, dep->rel, dep->page, dep->offset, dep->leafkey); } else gistentryinit(*e, (Datum) 0, r, pg, o, l); }
/* * Hash function for elements. * * We use the element type's default hash opclass, and the default collation * if the type is collation-sensitive. */ static uint32 element_hash(const void *key, Size keysize) { Datum d = *((const Datum *) key); Datum h; h = FunctionCall1Coll(array_extra_data->hash, DEFAULT_COLLATION_OID, d); return DatumGetUInt32(h); }
/* * _hash_datum2hashkey -- given a Datum, call the index's hash procedure * * The Datum is assumed to be of the index's column type, so we can use the * "primary" hash procedure that's tracked for us by the generic index code. */ uint32 _hash_datum2hashkey(Relation rel, Datum key) { FmgrInfo *procinfo; Oid collation; /* XXX assumes index has only one attribute */ procinfo = index_getprocinfo(rel, 1, HASHPROC); collation = rel->rd_indcollation[0]; return DatumGetUInt32(FunctionCall1Coll(procinfo, collation, key)); }
/* * initialize a GiST entry with fetched value in key field */ static Datum gistFetchAtt(GISTSTATE *giststate, int nkey, Datum k, Relation r) { GISTENTRY fentry; GISTENTRY *fep; gistentryinit(fentry, k, r, NULL, (OffsetNumber) 0, false); fep = (GISTENTRY *) DatumGetPointer(FunctionCall1Coll(&giststate->fetchFn[nkey], giststate->supportCollation[nkey], PointerGetDatum(&fentry))); /* fetchFn set 'key', return it to the caller */ return fep->key; }
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum attdata[], bool isnull[], bool isleaf) { Datum compatt[INDEX_MAX_KEYS]; int i; IndexTuple res; /* * Call the compress method on each attribute. */ for (i = 0; i < r->rd_att->natts; i++) { if (isnull[i]) compatt[i] = (Datum) 0; else { GISTENTRY centry; GISTENTRY *cep; gistentryinit(centry, attdata[i], r, NULL, (OffsetNumber) 0, isleaf); /* there may not be a compress function in opclass */ if (OidIsValid(giststate->compressFn[i].fn_oid)) cep = (GISTENTRY *) DatumGetPointer(FunctionCall1Coll(&giststate->compressFn[i], giststate->supportCollation[i], PointerGetDatum(¢ry))); else cep = ¢ry; compatt[i] = cep->key; } } res = index_form_tuple(giststate->tupdesc, compatt, isnull); /* * The offset number on tuples on internal pages is unused. For historical * reasons, it is set to 0xffff. */ ItemPointerSetOffsetNumber(&(res->t_tid), 0xffff); return res; }
/* * initialize a GiST entry with a compressed version of key */ void gistcentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, Datum k, Relation r, Page pg, OffsetNumber o, bool l, bool isNull) { if (!isNull) { GISTENTRY *cep; gistentryinit(*e, k, r, pg, o, l); cep = (GISTENTRY *) DatumGetPointer(FunctionCall1Coll(&giststate->compressFn[nkey], giststate->supportCollation[nkey], PointerGetDatum(e))); /* compressFn may just return the given pointer */ if (cep != e) gistentryinit(*e, cep->key, cep->rel, cep->page, cep->offset, cep->leafkey); } else gistentryinit(*e, (Datum) 0, r, pg, o, l); }