27
27
28
28
#include "bloom.h"
29
29
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 )
36
35
37
36
PG_FUNCTION_INFO_V1 (blhandler );
38
37
39
- /* Kind of relation optioms for bloom index */
38
+ /* Kind of relation options for bloom index */
40
39
static relopt_kind bl_relopt_kind ;
40
+ /* parse table for fillRelOptions */
41
+ static relopt_parse_elt bl_relopt_tab [INDEX_MAX_KEYS + 1 ];
41
42
42
43
static int32 myRand (void );
43
44
static void mySrand (uint32 seed );
44
45
45
46
/*
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().
47
50
*/
48
51
void
49
52
_PG_init (void )
@@ -53,17 +56,46 @@ _PG_init(void)
53
56
54
57
bl_relopt_kind = add_reloption_kind ();
55
58
59
+ /* Option for length of signature */
56
60
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 );
58
66
67
+ /* Number of bits for each possible index column: col1, col2, ... */
59
68
for (i = 0 ; i < INDEX_MAX_KEYS ; i ++ )
60
69
{
61
- snprintf (buf , 16 , "col%d" , i + 1 );
70
+ snprintf (buf , sizeof ( buf ) , "col%d" , i + 1 );
62
71
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 ]);
64
78
}
65
79
}
66
80
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
+
67
99
/*
68
100
* Bloom handler function: return IndexAmRoutine with access method parameters
69
101
* and callbacks.
@@ -157,7 +189,7 @@ initBloomState(BloomState *state, Relation index)
157
189
158
190
memcpy (& state -> opts , index -> rd_amcache , sizeof (state -> opts ));
159
191
state -> sizeOfBloomTuple = BLOOMTUPLEHDRSZ +
160
- sizeof (SignType ) * state -> opts .bloomLength ;
192
+ sizeof (BloomSignatureWord ) * state -> opts .bloomLength ;
161
193
}
162
194
163
195
/*
@@ -208,7 +240,7 @@ mySrand(uint32 seed)
208
240
* Add bits of given value to the signature.
209
241
*/
210
242
void
211
- signValue (BloomState * state , SignType * sign , Datum value , int attno )
243
+ signValue (BloomState * state , BloomSignatureWord * sign , Datum value , int attno )
212
244
{
213
245
uint32 hashVal ;
214
246
int nBit ,
@@ -231,8 +263,8 @@ signValue(BloomState *state, SignType *sign, Datum value, int attno)
231
263
232
264
for (j = 0 ; j < state -> opts .bitSize [attno ]; j ++ )
233
265
{
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 );
236
268
SETBIT (sign , nBit );
237
269
}
238
270
}
@@ -361,39 +393,6 @@ BloomInitPage(Page page, uint16 flags)
361
393
opaque -> bloom_page_id = BLOOM_PAGE_ID ;
362
394
}
363
395
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
-
397
396
/*
398
397
* Fill in metapage for bloom index.
399
398
*/
@@ -405,14 +404,11 @@ BloomFillMetapage(Relation index, Page metaPage)
405
404
406
405
/*
407
406
* 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.
411
408
*/
412
409
opts = (BloomOptions * ) index -> rd_options ;
413
410
if (!opts )
414
- opts = (BloomOptions * ) palloc0 (sizeof (BloomOptions ));
415
- adjustBloomOptions (opts );
411
+ opts = makeDefaultBloomOptions ();
416
412
417
413
/*
418
414
* Initialize contents of meta page, including a copy of the options,
@@ -462,30 +458,15 @@ bloptions(Datum reloptions, bool validate)
462
458
relopt_value * options ;
463
459
int numoptions ;
464
460
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
- }
482
461
462
+ /* Parse the user-given reloptions */
483
463
options = parseRelOptions (reloptions , validate , bl_relopt_kind , & numoptions );
484
464
rdopts = allocateReloptStruct (sizeof (BloomOptions ), options , numoptions );
485
465
fillRelOptions ((void * ) rdopts , sizeof (BloomOptions ), options , numoptions ,
486
- validate , tab , INDEX_MAX_KEYS + 1 );
466
+ validate , bl_relopt_tab , lengthof ( bl_relopt_tab ) );
487
467
488
- adjustBloomOptions (rdopts );
468
+ /* Convert signature length from # of bits to # to words, rounding up */
469
+ rdopts -> bloomLength = (rdopts -> bloomLength + SIGNWORDBITS - 1 ) / SIGNWORDBITS ;
489
470
490
471
return (bytea * ) rdopts ;
491
472
}
0 commit comments