diff options
Diffstat (limited to 'contrib/bloom/blutils.c')
-rw-r--r-- | contrib/bloom/blutils.c | 125 |
1 files changed, 53 insertions, 72 deletions
diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 4a5b343dd02..876952f2d5f 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -27,23 +27,26 @@ #include "bloom.h" -/* Signature dealing macros */ -#define BITSIGNTYPE (BITS_PER_BYTE * sizeof(SignType)) -#define GETWORD(x,i) ( *( (SignType*)(x) + (int)( (i) / BITSIGNTYPE ) ) ) -#define CLRBIT(x,i) GETWORD(x,i) &= ~( 0x01 << ( (i) % BITSIGNTYPE ) ) -#define SETBIT(x,i) GETWORD(x,i) |= ( 0x01 << ( (i) % BITSIGNTYPE ) ) -#define GETBIT(x,i) ( (GETWORD(x,i) >> ( (i) % BITSIGNTYPE )) & 0x01 ) +/* Signature dealing macros - note i is assumed to be of type int */ +#define GETWORD(x,i) ( *( (BloomSignatureWord *)(x) + ( (i) / SIGNWORDBITS ) ) ) +#define CLRBIT(x,i) GETWORD(x,i) &= ~( 0x01 << ( (i) % SIGNWORDBITS ) ) +#define SETBIT(x,i) GETWORD(x,i) |= ( 0x01 << ( (i) % SIGNWORDBITS ) ) +#define GETBIT(x,i) ( (GETWORD(x,i) >> ( (i) % SIGNWORDBITS )) & 0x01 ) PG_FUNCTION_INFO_V1(blhandler); -/* Kind of relation optioms for bloom index */ +/* Kind of relation options for bloom index */ static relopt_kind bl_relopt_kind; +/* parse table for fillRelOptions */ +static relopt_parse_elt bl_relopt_tab[INDEX_MAX_KEYS + 1]; static int32 myRand(void); static void mySrand(uint32 seed); /* - * Module initialize function: initilized relation options. + * Module initialize function: initialize info about Bloom relation options. + * + * Note: keep this in sync with makeDefaultBloomOptions(). */ void _PG_init(void) @@ -53,18 +56,47 @@ _PG_init(void) bl_relopt_kind = add_reloption_kind(); + /* Option for length of signature */ add_int_reloption(bl_relopt_kind, "length", - "Length of signature in uint16 type", 5, 1, 256); + "Length of signature in bits", + DEFAULT_BLOOM_LENGTH, 1, MAX_BLOOM_LENGTH); + bl_relopt_tab[0].optname = "length"; + bl_relopt_tab[0].opttype = RELOPT_TYPE_INT; + bl_relopt_tab[0].offset = offsetof(BloomOptions, bloomLength); + /* Number of bits for each possible index column: col1, col2, ... */ for (i = 0; i < INDEX_MAX_KEYS; i++) { - snprintf(buf, 16, "col%d", i + 1); + snprintf(buf, sizeof(buf), "col%d", i + 1); add_int_reloption(bl_relopt_kind, buf, - "Number of bits for corresponding column", 2, 1, 2048); + "Number of bits generated for each index column", + DEFAULT_BLOOM_BITS, 1, MAX_BLOOM_BITS); + bl_relopt_tab[i + 1].optname = MemoryContextStrdup(TopMemoryContext, + buf); + bl_relopt_tab[i + 1].opttype = RELOPT_TYPE_INT; + bl_relopt_tab[i + 1].offset = offsetof(BloomOptions, bitSize[i]); } } /* + * Construct a default set of Bloom options. + */ +static BloomOptions * +makeDefaultBloomOptions(void) +{ + BloomOptions *opts; + int i; + + opts = (BloomOptions *) palloc0(sizeof(BloomOptions)); + /* Convert DEFAULT_BLOOM_LENGTH from # of bits to # of words */ + opts->bloomLength = (DEFAULT_BLOOM_LENGTH + SIGNWORDBITS - 1) / SIGNWORDBITS; + for (i = 0; i < INDEX_MAX_KEYS; i++) + opts->bitSize[i] = DEFAULT_BLOOM_BITS; + SET_VARSIZE(opts, sizeof(BloomOptions)); + return opts; +} + +/* * Bloom handler function: return IndexAmRoutine with access method parameters * and callbacks. */ @@ -157,7 +189,7 @@ initBloomState(BloomState *state, Relation index) memcpy(&state->opts, index->rd_amcache, sizeof(state->opts)); state->sizeOfBloomTuple = BLOOMTUPLEHDRSZ + - sizeof(SignType) * state->opts.bloomLength; + sizeof(BloomSignatureWord) * state->opts.bloomLength; } /* @@ -208,7 +240,7 @@ mySrand(uint32 seed) * Add bits of given value to the signature. */ void -signValue(BloomState *state, SignType *sign, Datum value, int attno) +signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno) { uint32 hashVal; int nBit, @@ -231,8 +263,8 @@ signValue(BloomState *state, SignType *sign, Datum value, int attno) for (j = 0; j < state->opts.bitSize[attno]; j++) { - /* prevent mutiple evaluation */ - nBit = myRand() % (state->opts.bloomLength * BITSIGNTYPE); + /* prevent multiple evaluation in SETBIT macro */ + nBit = myRand() % (state->opts.bloomLength * SIGNWORDBITS); SETBIT(sign, nBit); } } @@ -362,39 +394,6 @@ BloomInitPage(Page page, uint16 flags) } /* - * Adjust options of bloom index. - * - * This must produce default options when *opts is initially all-zero. - */ -static void -adjustBloomOptions(BloomOptions *opts) -{ - int i; - - /* Default length of bloom filter is 5 of 16-bit integers */ - if (opts->bloomLength <= 0) - opts->bloomLength = 5; - else if (opts->bloomLength > MAX_BLOOM_LENGTH) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("length of bloom signature (%d) is greater than maximum %d", - opts->bloomLength, MAX_BLOOM_LENGTH))); - - /* Check signature length */ - for (i = 0; i < INDEX_MAX_KEYS; i++) - { - /* - * Zero and negative number of bits is meaningless. Also setting - * more bits than signature have seems useless. Replace both cases - * with 2 bits default. - */ - if (opts->bitSize[i] <= 0 - || opts->bitSize[i] >= opts->bloomLength * sizeof(SignType) * BITS_PER_BYTE) - opts->bitSize[i] = 2; - } -} - -/* * Fill in metapage for bloom index. */ void @@ -405,14 +404,11 @@ BloomFillMetapage(Relation index, Page metaPage) /* * Choose the index's options. If reloptions have been assigned, use - * those, otherwise create default options by applying adjustBloomOptions - * to a zeroed chunk of memory. We apply adjustBloomOptions to existing - * reloptions too, just out of paranoia; they should be valid already. + * those, otherwise create default options. */ opts = (BloomOptions *) index->rd_options; if (!opts) - opts = (BloomOptions *) palloc0(sizeof(BloomOptions)); - adjustBloomOptions(opts); + opts = makeDefaultBloomOptions(); /* * Initialize contents of meta page, including a copy of the options, @@ -462,30 +458,15 @@ bloptions(Datum reloptions, bool validate) relopt_value *options; int numoptions; BloomOptions *rdopts; - relopt_parse_elt tab[INDEX_MAX_KEYS + 1]; - int i; - char buf[16]; - - /* Option for length of signature */ - tab[0].optname = "length"; - tab[0].opttype = RELOPT_TYPE_INT; - tab[0].offset = offsetof(BloomOptions, bloomLength); - - /* Number of bits for each of possible columns: col1, col2, ... */ - for (i = 0; i < INDEX_MAX_KEYS; i++) - { - snprintf(buf, sizeof(buf), "col%d", i + 1); - tab[i + 1].optname = pstrdup(buf); - tab[i + 1].opttype = RELOPT_TYPE_INT; - tab[i + 1].offset = offsetof(BloomOptions, bitSize[i]); - } + /* Parse the user-given reloptions */ options = parseRelOptions(reloptions, validate, bl_relopt_kind, &numoptions); rdopts = allocateReloptStruct(sizeof(BloomOptions), options, numoptions); fillRelOptions((void *) rdopts, sizeof(BloomOptions), options, numoptions, - validate, tab, INDEX_MAX_KEYS + 1); + validate, bl_relopt_tab, lengthof(bl_relopt_tab)); - adjustBloomOptions(rdopts); + /* Convert signature length from # of bits to # to words, rounding up */ + rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS; return (bytea *) rdopts; } |