2727
2828#include "bloom.h"
2929
30- /* Signature dealing macros */
31- #define BITSIGNTYPE (BITS_PER_BYTE * sizeof(SignType))
32- #define GETWORD (x ,i ) ( *( (SignType*)(x) + (int)( (i) / BITSIGNTYPE ) ) )
33- #define CLRBIT (x ,i ) GETWORD(x,i) &= ~( 0x01 << ( (i) % BITSIGNTYPE ) )
34- #define SETBIT (x ,i ) GETWORD(x,i) |= ( 0x01 << ( (i) % BITSIGNTYPE ) )
35- #define GETBIT (x ,i ) ( (GETWORD(x,i) >> ( (i) % BITSIGNTYPE )) & 0x01 )
30+ /* Signature dealing macros - note i is assumed to be of type int */
31+ #define GETWORD (x ,i ) ( *( (BloomSignatureWord *)(x) + ( (i) / SIGNWORDBITS ) ) )
32+ #define CLRBIT (x ,i ) GETWORD(x,i) &= ~( 0x01 << ( (i) % SIGNWORDBITS ) )
33+ #define SETBIT (x ,i ) GETWORD(x,i) |= ( 0x01 << ( (i) % SIGNWORDBITS ) )
34+ #define GETBIT (x ,i ) ( (GETWORD(x,i) >> ( (i) % SIGNWORDBITS )) & 0x01 )
3635
3736PG_FUNCTION_INFO_V1 (blhandler );
3837
39- /* Kind of relationoptioms for bloom index */
38+ /* Kind of relationoptions for bloom index */
4039static relopt_kind bl_relopt_kind ;
40+ /* parse table for fillRelOptions */
41+ static relopt_parse_elt bl_relopt_tab [INDEX_MAX_KEYS + 1 ];
4142
4243static int32 myRand (void );
4344static void mySrand (uint32 seed );
4445
4546/*
46- * Module initialize function: initilized relation options.
47+ * Module initialize function: initialize info about Bloom relation options.
48+ *
49+ * Note: keep this in sync with makeDefaultBloomOptions().
4750 */
4851void
4952_PG_init (void )
@@ -53,17 +56,46 @@ _PG_init(void)
5356
5457bl_relopt_kind = add_reloption_kind ();
5558
59+ /* Option for length of signature */
5660add_int_reloption (bl_relopt_kind ,"length" ,
57- "Length of signature in uint16 type" ,5 ,1 ,256 );
61+ "Length of signature in bits" ,
62+ DEFAULT_BLOOM_LENGTH ,1 ,MAX_BLOOM_LENGTH );
63+ bl_relopt_tab [0 ].optname = "length" ;
64+ bl_relopt_tab [0 ].opttype = RELOPT_TYPE_INT ;
65+ bl_relopt_tab [0 ].offset = offsetof(BloomOptions ,bloomLength );
5866
67+ /* Number of bits for each possible index column: col1, col2, ... */
5968for (i = 0 ;i < INDEX_MAX_KEYS ;i ++ )
6069{
61- snprintf (buf ,16 ,"col%d" ,i + 1 );
70+ snprintf (buf ,sizeof ( buf ) ,"col%d" ,i + 1 );
6271add_int_reloption (bl_relopt_kind ,buf ,
63- "Number of bits for corresponding column" ,2 ,1 ,2048 );
72+ "Number of bits generated for each index column" ,
73+ DEFAULT_BLOOM_BITS ,1 ,MAX_BLOOM_BITS );
74+ bl_relopt_tab [i + 1 ].optname = MemoryContextStrdup (TopMemoryContext ,
75+ buf );
76+ bl_relopt_tab [i + 1 ].opttype = RELOPT_TYPE_INT ;
77+ bl_relopt_tab [i + 1 ].offset = offsetof(BloomOptions ,bitSize [i ]);
6478}
6579}
6680
81+ /*
82+ * Construct a default set of Bloom options.
83+ */
84+ static BloomOptions *
85+ makeDefaultBloomOptions (void )
86+ {
87+ BloomOptions * opts ;
88+ int i ;
89+
90+ opts = (BloomOptions * )palloc0 (sizeof (BloomOptions ));
91+ /* Convert DEFAULT_BLOOM_LENGTH from # of bits to # of words */
92+ opts -> bloomLength = (DEFAULT_BLOOM_LENGTH + SIGNWORDBITS - 1 ) /SIGNWORDBITS ;
93+ for (i = 0 ;i < INDEX_MAX_KEYS ;i ++ )
94+ opts -> bitSize [i ]= DEFAULT_BLOOM_BITS ;
95+ SET_VARSIZE (opts ,sizeof (BloomOptions ));
96+ return opts ;
97+ }
98+
6799/*
68100 * Bloom handler function: return IndexAmRoutine with access method parameters
69101 * and callbacks.
@@ -157,7 +189,7 @@ initBloomState(BloomState *state, Relation index)
157189
158190memcpy (& state -> opts ,index -> rd_amcache ,sizeof (state -> opts ));
159191state -> sizeOfBloomTuple = BLOOMTUPLEHDRSZ +
160- sizeof (SignType )* state -> opts .bloomLength ;
192+ sizeof (BloomSignatureWord )* state -> opts .bloomLength ;
161193}
162194
163195/*
@@ -208,7 +240,7 @@ mySrand(uint32 seed)
208240 * Add bits of given value to the signature.
209241 */
210242void
211- signValue (BloomState * state ,SignType * sign ,Datum value ,int attno )
243+ signValue (BloomState * state ,BloomSignatureWord * sign ,Datum value ,int attno )
212244{
213245uint32 hashVal ;
214246int nBit ,
@@ -231,8 +263,8 @@ signValue(BloomState *state, SignType *sign, Datum value, int attno)
231263
232264for (j = 0 ;j < state -> opts .bitSize [attno ];j ++ )
233265{
234- /* preventmutiple evaluation */
235- nBit = myRand () % (state -> opts .bloomLength * BITSIGNTYPE );
266+ /* preventmultiple evaluation in SETBIT macro */
267+ nBit = myRand () % (state -> opts .bloomLength * SIGNWORDBITS );
236268SETBIT (sign ,nBit );
237269}
238270}
@@ -361,39 +393,6 @@ BloomInitPage(Page page, uint16 flags)
361393opaque -> bloom_page_id = BLOOM_PAGE_ID ;
362394}
363395
364- /*
365- * Adjust options of bloom index.
366- *
367- * This must produce default options when *opts is initially all-zero.
368- */
369- static void
370- adjustBloomOptions (BloomOptions * opts )
371- {
372- int i ;
373-
374- /* Default length of bloom filter is 5 of 16-bit integers */
375- if (opts -> bloomLength <=0 )
376- opts -> bloomLength = 5 ;
377- else if (opts -> bloomLength > MAX_BLOOM_LENGTH )
378- ereport (ERROR ,
379- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
380- errmsg ("length of bloom signature (%d) is greater than maximum %d" ,
381- opts -> bloomLength ,MAX_BLOOM_LENGTH )));
382-
383- /* Check signature length */
384- for (i = 0 ;i < INDEX_MAX_KEYS ;i ++ )
385- {
386- /*
387- * Zero and negative number of bits is meaningless. Also setting
388- * more bits than signature have seems useless. Replace both cases
389- * with 2 bits default.
390- */
391- if (opts -> bitSize [i ] <=0
392- || opts -> bitSize [i ] >=opts -> bloomLength * sizeof (SignType )* BITS_PER_BYTE )
393- opts -> bitSize [i ]= 2 ;
394- }
395- }
396-
397396/*
398397 * Fill in metapage for bloom index.
399398 */
@@ -405,14 +404,11 @@ BloomFillMetapage(Relation index, Page metaPage)
405404
406405/*
407406 * Choose the index's options. If reloptions have been assigned, use
408- * those, otherwise create default options by applying adjustBloomOptions
409- * to a zeroed chunk of memory. We apply adjustBloomOptions to existing
410- * reloptions too, just out of paranoia; they should be valid already.
407+ * those, otherwise create default options.
411408 */
412409opts = (BloomOptions * )index -> rd_options ;
413410if (!opts )
414- opts = (BloomOptions * )palloc0 (sizeof (BloomOptions ));
415- adjustBloomOptions (opts );
411+ opts = makeDefaultBloomOptions ();
416412
417413/*
418414 * Initialize contents of meta page, including a copy of the options,
@@ -462,30 +458,15 @@ bloptions(Datum reloptions, bool validate)
462458relopt_value * options ;
463459int numoptions ;
464460BloomOptions * rdopts ;
465- relopt_parse_elt tab [INDEX_MAX_KEYS + 1 ];
466- int i ;
467- char buf [16 ];
468-
469- /* Option for length of signature */
470- tab [0 ].optname = "length" ;
471- tab [0 ].opttype = RELOPT_TYPE_INT ;
472- tab [0 ].offset = offsetof(BloomOptions ,bloomLength );
473-
474- /* Number of bits for each of possible columns: col1, col2, ... */
475- for (i = 0 ;i < INDEX_MAX_KEYS ;i ++ )
476- {
477- snprintf (buf ,sizeof (buf ),"col%d" ,i + 1 );
478- tab [i + 1 ].optname = pstrdup (buf );
479- tab [i + 1 ].opttype = RELOPT_TYPE_INT ;
480- tab [i + 1 ].offset = offsetof(BloomOptions ,bitSize [i ]);
481- }
482461
462+ /* Parse the user-given reloptions */
483463options = parseRelOptions (reloptions ,validate ,bl_relopt_kind ,& numoptions );
484464rdopts = allocateReloptStruct (sizeof (BloomOptions ),options ,numoptions );
485465fillRelOptions ((void * )rdopts ,sizeof (BloomOptions ),options ,numoptions ,
486- validate ,tab , INDEX_MAX_KEYS + 1 );
466+ validate ,bl_relopt_tab , lengthof ( bl_relopt_tab ) );
487467
488- adjustBloomOptions (rdopts );
468+ /* Convert signature length from # of bits to # to words, rounding up */
469+ rdopts -> bloomLength = (rdopts -> bloomLength + SIGNWORDBITS - 1 ) /SIGNWORDBITS ;
489470
490471return (bytea * )rdopts ;
491472}