Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

freespace.h File Reference

#include "storage/block.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
Include dependency graph for freespace.h:
This graph shows which files directly or indirectly include this file:

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)

Function Documentation

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