89
89
#include "access/visibilitymap.h"
90
90
#include "access/xlog.h"
91
91
#include "miscadmin.h"
92
- #include "port/pg_bitutils.h"
93
92
#include "storage/bufmgr.h"
94
93
#include "storage/lmgr.h"
95
94
#include "storage/smgr.h"
96
95
#include "utils/inval.h"
97
96
97
+
98
98
/*#define TRACE_VISIBILITYMAP */
99
99
100
100
/*
115
115
#define HEAPBLK_TO_MAPBYTE (x ) (((x) % HEAPBLOCKS_PER_PAGE) / HEAPBLOCKS_PER_BYTE)
116
116
#define HEAPBLK_TO_OFFSET (x ) (((x) % HEAPBLOCKS_PER_BYTE) * BITS_PER_HEAPBLOCK)
117
117
118
- /* Masks for bit counting bits in the visibility map. */
119
- #define VISIBLE_MASK64 0x5555555555555555 /* The lower bit of each bit pair */
120
- #define FROZEN_MASK64 0xaaaaaaaaaaaaaaaa /* The upper bit of each bit pair */
118
+ /* tables for fast counting of set bits for visible and frozen */
119
+ static const uint8 number_of_ones_for_visible [256 ] = {
120
+ 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 , 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 ,
121
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
122
+ 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 , 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 ,
123
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
124
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
125
+ 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 , 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 ,
126
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
127
+ 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 , 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 ,
128
+ 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 , 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 ,
129
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
130
+ 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 , 0 , 1 , 0 , 1 , 1 , 2 , 1 , 2 ,
131
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
132
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
133
+ 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 , 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 ,
134
+ 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 1 , 2 , 2 , 3 , 2 , 3 ,
135
+ 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4 , 2 , 3 , 2 , 3 , 3 , 4 , 3 , 4
136
+ };
137
+ static const uint8 number_of_ones_for_frozen [256 ] = {
138
+ 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 ,
139
+ 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 ,
140
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
141
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
142
+ 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 ,
143
+ 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 ,
144
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
145
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
146
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
147
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
148
+ 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 3 , 3 , 4 , 4 ,
149
+ 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 3 , 3 , 4 , 4 ,
150
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
151
+ 1 , 1 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 ,
152
+ 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 3 , 3 , 4 , 4 ,
153
+ 2 , 2 , 3 , 3 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 3 , 3 , 4 , 4
154
+ };
121
155
122
156
/* prototypes for internal routines */
123
157
static Buffer vm_readbuf (Relation rel , BlockNumber blkno , bool extend );
@@ -374,16 +408,18 @@ void
374
408
visibilitymap_count (Relation rel , BlockNumber * all_visible , BlockNumber * all_frozen )
375
409
{
376
410
BlockNumber mapBlock ;
377
- BlockNumber nvisible = 0 ;
378
- BlockNumber nfrozen = 0 ;
379
411
380
412
/* all_visible must be specified */
381
413
Assert (all_visible );
382
414
415
+ * all_visible = 0 ;
416
+ if (all_frozen )
417
+ * all_frozen = 0 ;
418
+
383
419
for (mapBlock = 0 ;; mapBlock ++ )
384
420
{
385
421
Buffer mapBuffer ;
386
- uint64 * map ;
422
+ unsigned char * map ;
387
423
int i ;
388
424
389
425
/*
@@ -400,30 +436,17 @@ visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_fro
400
436
* immediately stale anyway if anyone is concurrently setting or
401
437
* clearing bits, and we only really need an approximate value.
402
438
*/
403
- map = (uint64 * ) PageGetContents (BufferGetPage (mapBuffer ));
439
+ map = (unsigned char * ) PageGetContents (BufferGetPage (mapBuffer ));
404
440
405
- StaticAssertStmt (MAPSIZE % sizeof (uint64 ) == 0 ,
406
- "unsupported MAPSIZE" );
407
- if (all_frozen == NULL )
408
- {
409
- for (i = 0 ; i < MAPSIZE / sizeof (uint64 ); i ++ )
410
- nvisible += pg_popcount64 (map [i ] & VISIBLE_MASK64 );
411
- }
412
- else
441
+ for (i = 0 ; i < MAPSIZE ; i ++ )
413
442
{
414
- for (i = 0 ; i < MAPSIZE / sizeof (uint64 ); i ++ )
415
- {
416
- nvisible += pg_popcount64 (map [i ] & VISIBLE_MASK64 );
417
- nfrozen += pg_popcount64 (map [i ] & FROZEN_MASK64 );
418
- }
443
+ * all_visible += number_of_ones_for_visible [map [i ]];
444
+ if (all_frozen )
445
+ * all_frozen += number_of_ones_for_frozen [map [i ]];
419
446
}
420
447
421
448
ReleaseBuffer (mapBuffer );
422
449
}
423
-
424
- * all_visible = nvisible ;
425
- if (all_frozen )
426
- * all_frozen = nfrozen ;
427
450
}
428
451
429
452
/*
0 commit comments