#include "storage/block.h"#include "storage/relfilenode.h"#include "utils/relcache.h"

Go to the source code of this file.
Functions | |
| Size | GetRecordedFreeSpace (Relation rel, BlockNumber heapBlk) |
| BlockNumber | GetPageWithFreeSpace (Relation rel, Size spaceNeeded) |
| BlockNumber | RecordAndGetPageWithFreeSpace (Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded) |
| void | RecordPageWithFreeSpace (Relation rel, BlockNumber heapBlk, Size spaceAvail) |
| void | XLogRecordPageWithFreeSpace (RelFileNode rnode, BlockNumber heapBlk, Size spaceAvail) |
| void | FreeSpaceMapTruncateRel (Relation rel, BlockNumber nblocks) |
| void | FreeSpaceMapVacuum (Relation rel) |
| void FreeSpaceMapTruncateRel | ( | Relation | rel, | |
| BlockNumber | nblocks | |||
| ) |
Definition at line 257 of file freespace.c.
References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, FSM_FORKNUM, fsm_get_location(), fsm_logical_to_physical(), fsm_readbuf(), fsm_truncate_avail(), LockBuffer(), MarkBufferDirtyHint(), RelationData::rd_smgr, RelationOpenSmgr, SMgrRelationData::smgr_fsm_nblocks, smgrexists(), smgrnblocks(), smgrtruncate(), and UnlockReleaseBuffer().
Referenced by RelationTruncate(), and smgr_redo().
{
BlockNumber new_nfsmblocks;
FSMAddress first_removed_address;
uint16 first_removed_slot;
Buffer buf;
RelationOpenSmgr(rel);
/*
* If no FSM has been created yet for this relation, there's nothing to
* truncate.
*/
if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
return;
/* Get the location in the FSM of the first removed heap block */
first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
/*
* Zero out the tail of the last remaining FSM page. If the slot
* representing the first removed heap block is at a page boundary, as the
* first slot on the FSM page that first_removed_address points to, we can
* just truncate that page altogether.
*/
if (first_removed_slot > 0)
{
buf = fsm_readbuf(rel, first_removed_address, false);
if (!BufferIsValid(buf))
return; /* nothing to do; the FSM was already smaller */
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
MarkBufferDirtyHint(buf);
UnlockReleaseBuffer(buf);
new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1;
}
else
{
new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
return; /* nothing to do; the FSM was already smaller */
}
/* Truncate the unused FSM pages, and send smgr inval message */
smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks);
/*
* We might as well update the local smgr_fsm_nblocks setting.
* smgrtruncate sent an smgr cache inval message, which will cause other
* backends to invalidate their copy of smgr_fsm_nblocks, and this one too
* at the next command boundary. But this ensures it isn't outright wrong
* until then.
*/
if (rel->rd_smgr)
rel->rd_smgr->smgr_fsm_nblocks = new_nfsmblocks;
}
| void FreeSpaceMapVacuum | ( | Relation | rel | ) |
Definition at line 319 of file freespace.c.
References fsm_vacuum_page().
Referenced by IndexFreeSpaceMapVacuum(), and lazy_vacuum_rel().
{
bool dummy;
/*
* Traverse the tree in depth-first order. The tree is stored physically
* in depth-first order, so this should be pretty I/O efficient.
*/
fsm_vacuum_page(rel, FSM_ROOT_ADDRESS, &dummy);
}
| BlockNumber GetPageWithFreeSpace | ( | Relation | rel, | |
| Size | spaceNeeded | |||
| ) |
Definition at line 130 of file freespace.c.
References fsm_search(), and fsm_space_needed_to_cat().
Referenced by GetFreeIndexPage(), and RelationGetBufferForTuple().
{
uint8 min_cat = fsm_space_needed_to_cat(spaceNeeded);
return fsm_search(rel, min_cat);
}
| Size GetRecordedFreeSpace | ( | Relation | rel, | |
| BlockNumber | heapBlk | |||
| ) |
Definition at line 228 of file freespace.c.
References buf, BufferGetPage, BufferIsValid, fsm_get_avail(), fsm_get_location(), fsm_readbuf(), fsm_space_cat_to_avail(), and ReleaseBuffer().
Referenced by pg_freespace().
{
FSMAddress addr;
uint16 slot;
Buffer buf;
uint8 cat;
/* Get the location of the FSM byte representing the heap block */
addr = fsm_get_location(heapBlk, &slot);
buf = fsm_readbuf(rel, addr, false);
if (!BufferIsValid(buf))
return 0;
cat = fsm_get_avail(BufferGetPage(buf), slot);
ReleaseBuffer(buf);
return fsm_space_cat_to_avail(cat);
}
| BlockNumber RecordAndGetPageWithFreeSpace | ( | Relation | rel, | |
| BlockNumber | oldPage, | |||
| Size | oldSpaceAvail, | |||
| Size | spaceNeeded | |||
| ) |
Definition at line 147 of file freespace.c.
References fsm_get_heap_blk(), fsm_get_location(), fsm_search(), fsm_set_and_search(), fsm_space_avail_to_cat(), and fsm_space_needed_to_cat().
Referenced by RelationGetBufferForTuple().
{
int old_cat = fsm_space_avail_to_cat(oldSpaceAvail);
int search_cat = fsm_space_needed_to_cat(spaceNeeded);
FSMAddress addr;
uint16 slot;
int search_slot;
/* Get the location of the FSM byte representing the heap block */
addr = fsm_get_location(oldPage, &slot);
search_slot = fsm_set_and_search(rel, addr, slot, old_cat, search_cat);
/*
* If fsm_set_and_search found a suitable new block, return that.
* Otherwise, search as usual.
*/
if (search_slot != -1)
return fsm_get_heap_blk(addr, search_slot);
else
return fsm_search(rel, search_cat);
}
| void RecordPageWithFreeSpace | ( | Relation | rel, | |
| BlockNumber | heapBlk, | |||
| Size | spaceAvail | |||
| ) |
Definition at line 179 of file freespace.c.
References fsm_get_location(), fsm_set_and_search(), and fsm_space_avail_to_cat().
Referenced by lazy_scan_heap(), lazy_vacuum_heap(), RecordFreeIndexPage(), and RecordUsedIndexPage().
{
int new_cat = fsm_space_avail_to_cat(spaceAvail);
FSMAddress addr;
uint16 slot;
/* Get the location of the FSM byte representing the heap block */
addr = fsm_get_location(heapBlk, &slot);
fsm_set_and_search(rel, addr, slot, new_cat, 0);
}
| void XLogRecordPageWithFreeSpace | ( | RelFileNode | rnode, | |
| BlockNumber | heapBlk, | |||
| Size | spaceAvail | |||
| ) |
Definition at line 196 of file freespace.c.
References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, FSM_FORKNUM, fsm_get_location(), fsm_logical_to_physical(), fsm_set_avail(), fsm_space_avail_to_cat(), LockBuffer(), MarkBufferDirtyHint(), PageInit(), PageIsNew, RBM_ZERO_ON_ERROR, UnlockReleaseBuffer(), and XLogReadBufferExtended().
Referenced by heap_xlog_clean(), heap_xlog_insert(), heap_xlog_multi_insert(), and heap_xlog_update().
{
int new_cat = fsm_space_avail_to_cat(spaceAvail);
FSMAddress addr;
uint16 slot;
BlockNumber blkno;
Buffer buf;
Page page;
/* Get the location of the FSM byte representing the heap block */
addr = fsm_get_location(heapBlk, &slot);
blkno = fsm_logical_to_physical(addr);
/* If the page doesn't exist already, extend */
buf = XLogReadBufferExtended(rnode, FSM_FORKNUM, blkno, RBM_ZERO_ON_ERROR);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
page = BufferGetPage(buf);
if (PageIsNew(page))
PageInit(page, BLCKSZ, 0);
if (fsm_set_avail(page, slot, new_cat))
MarkBufferDirtyHint(buf);
UnlockReleaseBuffer(buf);
}
1.7.1