|
16 | 16 | *visibilitymap_pin_ok - check whether correct map page is already pinned
|
17 | 17 | *visibilitymap_set - set a bit in a previously pinned page
|
18 | 18 | *visibilitymap_test - test if a bit is set
|
| 19 | + *visibilitymap_count - count number of bits set in visibility map |
| 20 | + *visibilitymap_truncate- truncate the visibility map |
19 | 21 | *
|
20 | 22 | * NOTES
|
21 | 23 | *
|
|
110 | 112 | #defineHEAPBLK_TO_MAPBYTE(x) (((x) % HEAPBLOCKS_PER_PAGE) / HEAPBLOCKS_PER_BYTE)
|
111 | 113 | #defineHEAPBLK_TO_MAPBIT(x) ((x) % HEAPBLOCKS_PER_BYTE)
|
112 | 114 |
|
| 115 | +/* table for fast counting of set bits */ |
| 116 | +staticconstuint8number_of_ones[256]= { |
| 117 | +0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, |
| 118 | +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, |
| 119 | +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, |
| 120 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 121 | +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, |
| 122 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 123 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 124 | +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, |
| 125 | +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, |
| 126 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 127 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 128 | +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, |
| 129 | +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, |
| 130 | +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, |
| 131 | +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, |
| 132 | +4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 |
| 133 | +}; |
| 134 | + |
113 | 135 | /* prototypes for internal routines */
|
114 | 136 | staticBuffervm_readbuf(Relationrel,BlockNumberblkno,boolextend);
|
115 | 137 | staticvoidvm_extend(Relationrel,BlockNumbernvmblocks);
|
@@ -307,6 +329,52 @@ visibilitymap_test(Relation rel, BlockNumber heapBlk, Buffer *buf)
|
307 | 329 | returnresult;
|
308 | 330 | }
|
309 | 331 |
|
| 332 | +/* |
| 333 | + *visibilitymap_count - count number of bits set in visibility map |
| 334 | + * |
| 335 | + * Note: we ignore the possibility of race conditions when the table is being |
| 336 | + * extended concurrently with the call. New pages added to the table aren't |
| 337 | + * going to be marked all-visible, so they won't affect the result. |
| 338 | + */ |
| 339 | +BlockNumber |
| 340 | +visibilitymap_count(Relationrel) |
| 341 | +{ |
| 342 | +BlockNumberresult=0; |
| 343 | +BlockNumbermapBlock; |
| 344 | + |
| 345 | +for (mapBlock=0; ;mapBlock++) |
| 346 | +{ |
| 347 | +BuffermapBuffer; |
| 348 | +unsignedchar*map; |
| 349 | +inti; |
| 350 | + |
| 351 | +/* |
| 352 | + * Read till we fall off the end of the map. We assume that any |
| 353 | + * extra bytes in the last page are zeroed, so we don't bother |
| 354 | + * excluding them from the count. |
| 355 | + */ |
| 356 | +mapBuffer=vm_readbuf(rel,mapBlock, false); |
| 357 | +if (!BufferIsValid(mapBuffer)) |
| 358 | +break; |
| 359 | + |
| 360 | +/* |
| 361 | + * We choose not to lock the page, since the result is going to be |
| 362 | + * immediately stale anyway if anyone is concurrently setting or |
| 363 | + * clearing bits, and we only really need an approximate value. |
| 364 | + */ |
| 365 | +map= (unsignedchar*)PageGetContents(BufferGetPage(mapBuffer)); |
| 366 | + |
| 367 | +for (i=0;i<MAPSIZE;i++) |
| 368 | +{ |
| 369 | +result+=number_of_ones[map[i]]; |
| 370 | +} |
| 371 | + |
| 372 | +ReleaseBuffer(mapBuffer); |
| 373 | +} |
| 374 | + |
| 375 | +returnresult; |
| 376 | +} |
| 377 | + |
310 | 378 | /*
|
311 | 379 | *visibilitymap_truncate - truncate the visibility map
|
312 | 380 | *
|
|