@@ -373,6 +373,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
373
373
int * nkeys ,
374
374
* nnullkeys ;
375
375
int keyno ;
376
+ char * ptr ;
377
+ Size len ;
378
+ char * tmp PG_USED_FOR_ASSERTS_ONLY ;
376
379
377
380
opaque = (BrinOpaque * ) scan -> opaque ;
378
381
bdesc = opaque -> bo_bdesc ;
@@ -403,15 +406,52 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
403
406
* We keep null and regular keys separate, so that we can pass just the
404
407
* regular keys to the consistent function easily.
405
408
*
409
+ * To reduce the allocation overhead, we allocate one big chunk and then
410
+ * carve it into smaller arrays ourselves. All the pieces have exactly the
411
+ * same lifetime, so that's OK.
412
+ *
406
413
* XXX The widest index can have 32 attributes, so the amount of wasted
407
414
* memory is negligible. We could invent a more compact approach (with
408
415
* just space for used attributes) but that would make the matching more
409
416
* complex so it's not a good trade-off.
410
417
*/
411
- keys = palloc0 (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts );
412
- nullkeys = palloc0 (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts );
413
- nkeys = palloc0 (sizeof (int ) * bdesc -> bd_tupdesc -> natts );
414
- nnullkeys = palloc0 (sizeof (int ) * bdesc -> bd_tupdesc -> natts );
418
+ len =
419
+ MAXALIGN (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts ) + /* regular keys */
420
+ MAXALIGN (sizeof (ScanKey ) * scan -> numberOfKeys ) * bdesc -> bd_tupdesc -> natts +
421
+ MAXALIGN (sizeof (int ) * bdesc -> bd_tupdesc -> natts ) +
422
+ MAXALIGN (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts ) + /* NULL keys */
423
+ MAXALIGN (sizeof (ScanKey ) * scan -> numberOfKeys ) * bdesc -> bd_tupdesc -> natts +
424
+ MAXALIGN (sizeof (int ) * bdesc -> bd_tupdesc -> natts );
425
+
426
+ ptr = palloc (len );
427
+ tmp = ptr ;
428
+
429
+ keys = (ScanKey * * ) ptr ;
430
+ ptr += MAXALIGN (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts );
431
+
432
+ nullkeys = (ScanKey * * ) ptr ;
433
+ ptr += MAXALIGN (sizeof (ScanKey * ) * bdesc -> bd_tupdesc -> natts );
434
+
435
+ nkeys = (int * ) ptr ;
436
+ ptr += MAXALIGN (sizeof (int ) * bdesc -> bd_tupdesc -> natts );
437
+
438
+ nnullkeys = (int * ) ptr ;
439
+ ptr += MAXALIGN (sizeof (int ) * bdesc -> bd_tupdesc -> natts );
440
+
441
+ for (int i = 0 ; i < bdesc -> bd_tupdesc -> natts ; i ++ )
442
+ {
443
+ keys [i ] = (ScanKey * ) ptr ;
444
+ ptr += MAXALIGN (sizeof (ScanKey ) * scan -> numberOfKeys );
445
+
446
+ nullkeys [i ] = (ScanKey * ) ptr ;
447
+ ptr += MAXALIGN (sizeof (ScanKey ) * scan -> numberOfKeys );
448
+ }
449
+
450
+ Assert (tmp + len == ptr );
451
+
452
+ /* zero the number of keys */
453
+ memset (nkeys , 0 , sizeof (int ) * bdesc -> bd_tupdesc -> natts );
454
+ memset (nnullkeys , 0 , sizeof (int ) * bdesc -> bd_tupdesc -> natts );
415
455
416
456
/* Preprocess the scan keys - split them into per-attribute arrays. */
417
457
for (keyno = 0 ; keyno < scan -> numberOfKeys ; keyno ++ )
@@ -443,9 +483,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
443
483
{
444
484
FmgrInfo * tmp ;
445
485
446
- /* No key/null arrays for this attribute. */
447
- Assert (( keys [ keyattno - 1 ] == NULL ) && ( nkeys [keyattno - 1 ] == 0 ) );
448
- Assert (( nullkeys [ keyattno - 1 ] == NULL ) && ( nnullkeys [keyattno - 1 ] == 0 ) );
486
+ /* First time we see this attribute, so no key/null keys . */
487
+ Assert (nkeys [keyattno - 1 ] == 0 );
488
+ Assert (nnullkeys [keyattno - 1 ] == 0 );
449
489
450
490
tmp = index_getprocinfo (idxRel , keyattno ,
451
491
BRIN_PROCNUM_CONSISTENT );
@@ -456,17 +496,11 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
456
496
/* Add key to the proper per-attribute array. */
457
497
if (key -> sk_flags & SK_ISNULL )
458
498
{
459
- if (!nullkeys [keyattno - 1 ])
460
- nullkeys [keyattno - 1 ] = palloc0 (sizeof (ScanKey ) * scan -> numberOfKeys );
461
-
462
499
nullkeys [keyattno - 1 ][nnullkeys [keyattno - 1 ]] = key ;
463
500
nnullkeys [keyattno - 1 ]++ ;
464
501
}
465
502
else
466
503
{
467
- if (!keys [keyattno - 1 ])
468
- keys [keyattno - 1 ] = palloc0 (sizeof (ScanKey ) * scan -> numberOfKeys );
469
-
470
504
keys [keyattno - 1 ][nkeys [keyattno - 1 ]] = key ;
471
505
nkeys [keyattno - 1 ]++ ;
472
506
}
0 commit comments