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 relation optioms for bloom index */
38+ /* Kind of relation options 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
5457 bl_relopt_kind = add_reloption_kind ();
5558
59+ /* Option for length of signature */
5660 add_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, ... */
5968 for (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 );
6271 add_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
158190 memcpy (& state -> opts , index -> rd_amcache , sizeof (state -> opts ));
159191 state -> 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{
213245 uint32 hashVal ;
214246 int nBit ,
@@ -231,8 +263,8 @@ signValue(BloomState *state, SignType *sign, Datum value, int attno)
231263
232264 for (j = 0 ; j < state -> opts .bitSize [attno ]; j ++ )
233265 {
234- /* prevent mutiple evaluation */
235- nBit = myRand () % (state -> opts .bloomLength * BITSIGNTYPE );
266+ /* prevent multiple evaluation in SETBIT macro */
267+ nBit = myRand () % (state -> opts .bloomLength * SIGNWORDBITS );
236268 SETBIT (sign , nBit );
237269 }
238270}
@@ -361,39 +393,6 @@ BloomInitPage(Page page, uint16 flags)
361393 opaque -> 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 */
412409 opts = (BloomOptions * ) index -> rd_options ;
413410 if (!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)
462458 relopt_value * options ;
463459 int numoptions ;
464460 BloomOptions * 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 */
483463 options = parseRelOptions (reloptions , validate , bl_relopt_kind , & numoptions );
484464 rdopts = allocateReloptStruct (sizeof (BloomOptions ), options , numoptions );
485465 fillRelOptions ((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
490471 return (bytea * ) rdopts ;
491472}
0 commit comments