#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); }