Header And Logo

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

Data Structures | Defines | Typedefs | Functions

bufpage.h File Reference

#include "access/xlogdefs.h"
#include "storage/block.h"
#include "storage/item.h"
#include "storage/off.h"
Include dependency graph for bufpage.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PageXLogRecPtr
struct  PageHeaderData

Defines

#define PageXLogRecPtrGet(val)   ((uint64) (val).xlogid << 32 | (val).xrecoff)
#define PageXLogRecPtrSet(ptr, lsn)   ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))
#define PD_HAS_FREE_LINES   0x0001
#define PD_PAGE_FULL   0x0002
#define PD_ALL_VISIBLE   0x0004
#define PD_VALID_FLAG_BITS   0x0007
#define PG_PAGE_LAYOUT_VERSION   4
#define PG_DATA_CHECKSUM_VERSION   1
#define PageIsValid(page)   PointerIsValid(page)
#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))
#define PageIsEmpty(page)   (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData)
#define PageIsNew(page)   (((PageHeader) (page))->pd_upper == 0)
#define PageGetItemId(page, offsetNumber)   ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1]))
#define PageGetContents(page)   ((char *) (page) + MAXALIGN(SizeOfPageHeaderData))
#define PageSizeIsValid(pageSize)   ((pageSize) == BLCKSZ)
#define PageGetPageSize(page)   ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))
#define PageGetPageLayoutVersion(page)   (((PageHeader) (page))->pd_pagesize_version & 0x00FF)
#define PageSetPageSizeAndVersion(page, size, version)
#define PageGetSpecialSize(page)   ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
#define PageGetSpecialPointer(page)
#define PageGetItem(page, itemId)
#define PageGetMaxOffsetNumber(page)
#define PageGetLSN(page)   PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn)
#define PageSetLSN(page, lsn)   PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn)
#define PageHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES)
#define PageSetHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES)
#define PageClearHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES)
#define PageIsFull(page)   (((PageHeader) (page))->pd_flags & PD_PAGE_FULL)
#define PageSetFull(page)   (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL)
#define PageClearFull(page)   (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL)
#define PageIsAllVisible(page)   (((PageHeader) (page))->pd_flags & PD_ALL_VISIBLE)
#define PageSetAllVisible(page)   (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE)
#define PageClearAllVisible(page)   (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE)
#define PageIsPrunable(page, oldestxmin)
#define PageSetPrunable(page, xid)
#define PageClearPrunable(page)   (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId)

Typedefs

typedef Pointer Page
typedef uint16 LocationIndex
typedef struct PageHeaderData PageHeaderData
typedef PageHeaderDataPageHeader

Functions

void PageInit (Page page, Size pageSize, Size specialSize)
bool PageIsVerified (Page page, BlockNumber blkno)
OffsetNumber PageAddItem (Page page, Item item, Size size, OffsetNumber offsetNumber, bool overwrite, bool is_heap)
Page PageGetTempPage (Page page)
Page PageGetTempPageCopy (Page page)
Page PageGetTempPageCopySpecial (Page page)
void PageRestoreTempPage (Page tempPage, Page oldPage)
void PageRepairFragmentation (Page page)
Size PageGetFreeSpace (Page page)
Size PageGetExactFreeSpace (Page page)
Size PageGetHeapFreeSpace (Page page)
void PageIndexTupleDelete (Page page, OffsetNumber offset)
void PageIndexMultiDelete (Page page, OffsetNumber *itemnos, int nitems)
char * PageSetChecksumCopy (Page page, BlockNumber blkno)
void PageSetChecksumInplace (Page page, BlockNumber blkno)

Define Documentation

#define PageClearAllVisible (   page  )     (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE)
#define PageClearFull (   page  )     (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL)

Definition at line 360 of file bufpage.h.

Referenced by heap_page_prune().

#define PageClearHasFreeLinePointers (   page  )     (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES)

Definition at line 353 of file bufpage.h.

Referenced by PageAddItem(), and PageRepairFragmentation().

#define PageClearPrunable (   page  )     (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId)

Definition at line 383 of file bufpage.h.

#define PageGetContents (   page  )     ((char *) (page) + MAXALIGN(SizeOfPageHeaderData))
#define PageGetItem (   page,
  itemId 
)
Value:
( \
    AssertMacro(PageIsValid(page)), \
    AssertMacro(ItemIdHasStorage(itemId)), \
    (Item)(((char *)(page)) + ItemIdGetOffset(itemId)) \
)

Definition at line 318 of file bufpage.h.

Referenced by _bt_buildadd(), _bt_check_unique(), _bt_checkkeys(), _bt_compare(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_isequal(), _bt_killitems(), _bt_newroot(), _bt_pagedel(), _bt_search(), _bt_split(), _hash_binsearch(), _hash_binsearch_last(), _hash_first(), _hash_next(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addLeafTuple(), addOrReplaceTuple(), bitgetpage(), BitmapHeapNext(), bt_page_items(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_delete_page(), btree_xlog_newroot(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), collectMatchBitmap(), collectMatchesForHeapRow(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), fill_seq_with_data(), GetBTPageStatistics(), getRightMostTuple(), GetTupleForTrigger(), ginbulkdelete(), ginEntryInsert(), ginRedoInsert(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), hashbulkdelete(), hashgettuple(), heap_delete(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_prune_chain(), heap_update(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapgetpage(), heapgettup(), heapgettup_pagemode(), lazy_check_needs_freeze(), lazy_scan_heap(), matchPartialInPendingList(), moveLeafs(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgWalk(), startScanEntry(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().

#define PageGetItemId (   page,
  offsetNumber 
)    ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1]))

Definition at line 232 of file bufpage.h.

Referenced by _bt_buildadd(), _bt_check_unique(), _bt_checkkeys(), _bt_compare(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_isequal(), _bt_killitems(), _bt_newroot(), _bt_pagedel(), _bt_search(), _bt_slideleft(), _bt_split(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_first(), _hash_next(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addLeafTuple(), addOrReplaceTuple(), bitgetpage(), BitmapHeapNext(), bt_page_items(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_delete_page(), btree_xlog_newroot(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), collectMatchBitmap(), collectMatchesForHeapRow(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), fill_seq_with_data(), GetBTPageStatistics(), getRightMostTuple(), GetTupleForTrigger(), ginbulkdelete(), ginEntryInsert(), ginRedoInsert(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), hashbulkdelete(), hashgetbitmap(), hashgettuple(), heap_delete(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_page_prune_execute(), heap_prune_chain(), heap_update(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapgetpage(), heapgettup(), heapgettup_pagemode(), lazy_check_needs_freeze(), lazy_scan_heap(), lazy_vacuum_page(), matchPartialInPendingList(), moveLeafs(), PageAddItem(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageRepairFragmentation(), pgstat_index_page(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgWalk(), startScanEntry(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().

#define PageGetLSN (   page  )     PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn)
#define PageGetMaxOffsetNumber (   page  ) 
Value:
(((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData ? 0 : \
     ((((PageHeader) (page))->pd_lower - SizeOfPageHeaderData) \
      / sizeof(ItemIdData)))

Definition at line 335 of file bufpage.h.

Referenced by _bt_binsrch(), _bt_check_unique(), _bt_checkkeys(), _bt_endpoint(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_killitems(), _bt_pagedel(), _bt_parent_deletion_safe(), _bt_readpage(), _bt_slideleft(), _bt_split(), _bt_steppage(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addOrReplaceTuple(), bitgetpage(), bt_page_items(), btree_xlog_delete_page(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryLocateEntry(), entryLocateLeafEntry(), entrySplitPage(), GetBTPageStatistics(), getRightMostTuple(), ginbulkdelete(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginRedoInsert(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginvacuumcleanup(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistextractpage(), gistfillbuffer(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistMemorizeAllDownlinks(), gistRedoPageUpdateRecord(), gistScanPage(), hashbulkdelete(), hashgettuple(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_insert(), heap_multi_insert(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_prune_chain(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heapgetpage(), heapgettup(), lazy_check_needs_freeze(), lazy_scan_heap(), log_heap_update(), moveLeafs(), moveRightIfItNeeded(), PageAddItem(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageRepairFragmentation(), pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), processPendingPage(), scanGetCandidate(), SpGistPageAddNewItem(), spgRedoVacuumRedirect(), spgWalk(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().

#define PageGetPageLayoutVersion (   page  )     (((PageHeader) (page))->pd_pagesize_version & 0x00FF)

Definition at line 272 of file bufpage.h.

Referenced by page_header().

#define PageGetPageSize (   page  )     ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))
#define PageGetSpecialPointer (   page  ) 
#define PageGetSpecialSize (   page  )     ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
#define PageHasFreeLinePointers (   page  )     (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES)

Definition at line 349 of file bufpage.h.

Referenced by PageAddItem(), and PageGetHeapFreeSpace().

#define PageIsAllVisible (   page  )     (((PageHeader) (page))->pd_flags & PD_ALL_VISIBLE)
#define PageIsEmpty (   page  )     (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData)
#define PageIsFull (   page  )     (((PageHeader) (page))->pd_flags & PD_PAGE_FULL)

Definition at line 356 of file bufpage.h.

Referenced by heap_page_prune(), and heap_page_prune_opt().

#define PageIsNew (   page  )     (((PageHeader) (page))->pd_upper == 0)
#define PageIsPrunable (   page,
  oldestxmin 
)
Value:
( \
    AssertMacro(TransactionIdIsNormal(oldestxmin)), \
    TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) && \
    TransactionIdPrecedes(((PageHeader) (page))->pd_prune_xid, oldestxmin) \
)

Definition at line 370 of file bufpage.h.

Referenced by heap_page_prune_opt().

#define PageIsValid (   page  )     PointerIsValid(page)

Definition at line 208 of file bufpage.h.

#define PageSetAllVisible (   page  )     (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE)

Definition at line 365 of file bufpage.h.

Referenced by heap_xlog_visible(), lazy_scan_heap(), and lazy_vacuum_page().

#define PageSetFull (   page  )     (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL)

Definition at line 358 of file bufpage.h.

Referenced by heap_update().

#define PageSetHasFreeLinePointers (   page  )     (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES)

Definition at line 351 of file bufpage.h.

Referenced by PageRepairFragmentation().

#define PageSetLSN (   page,
  lsn 
)    PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn)

Definition at line 346 of file bufpage.h.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_newroot(), _bt_pagedel(), _bt_restore_meta(), _bt_split(), addLeafTuple(), AlterSequence(), btree_xlog_delete(), btree_xlog_delete_page(), btree_xlog_insert(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_vacuum(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_with_data(), ginbuild(), ginDeletePage(), ginHeapTupleFastInsert(), ginInsertValue(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginUpdateStats(), gistbuild(), gistbulkdelete(), gistplacetopage(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), heap_delete(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_page_prune(), heap_update(), heap_xlog_clean(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_newpage(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_page(), log_newpage(), log_newpage_buffer(), MarkBufferDirtyHint(), moveLeafs(), nextval_internal(), RestoreBackupBlockContents(), seq_redo(), shiftList(), spgAddNodeAction(), spgbuild(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), visibilitymap_set(), writeListPage(), and xlogVacuumPage().

#define PageSetPageSizeAndVersion (   page,
  size,
  version 
)
Value:
( \
    AssertMacro(((size) & 0xFF00) == (size)), \
    AssertMacro(((version) & 0x00FF) == (version)), \
    ((PageHeader) (page))->pd_pagesize_version = (size) | (version) \
)

Definition at line 282 of file bufpage.h.

Referenced by PageInit().

#define PageSetPrunable (   page,
  xid 
)
Value:
do { \
    Assert(TransactionIdIsNormal(xid)); \
    if (!TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) || \
        TransactionIdPrecedes(xid, ((PageHeader) (page))->pd_prune_xid)) \
        ((PageHeader) (page))->pd_prune_xid = (xid); \
} while (0)

Definition at line 376 of file bufpage.h.

Referenced by heap_delete(), heap_update(), heap_xlog_delete(), and heap_xlog_update().

#define PageSizeIsValid (   pageSize  )     ((pageSize) == BLCKSZ)

Definition at line 255 of file bufpage.h.

#define PageXLogRecPtrGet (   val  )     ((uint64) (val).xlogid << 32 | (val).xrecoff)

Definition at line 96 of file bufpage.h.

#define PageXLogRecPtrSet (   ptr,
  lsn 
)    ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))

Definition at line 98 of file bufpage.h.

#define PD_ALL_VISIBLE   0x0004

Definition at line 179 of file bufpage.h.

#define PD_HAS_FREE_LINES   0x0001

Definition at line 176 of file bufpage.h.

#define PD_PAGE_FULL   0x0002

Definition at line 177 of file bufpage.h.

#define PD_VALID_FLAG_BITS   0x0007

Definition at line 182 of file bufpage.h.

Referenced by PageIsVerified().

#define PG_DATA_CHECKSUM_VERSION   1

Definition at line 197 of file bufpage.h.

#define PG_PAGE_LAYOUT_VERSION   4

Definition at line 196 of file bufpage.h.

Referenced by PageInit().

#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))

Typedef Documentation

Definition at line 83 of file bufpage.h.

typedef Pointer Page

Definition at line 74 of file bufpage.h.

Definition at line 162 of file bufpage.h.


Function Documentation

OffsetNumber PageAddItem ( Page  page,
Item  item,
Size  size,
OffsetNumber  offsetNumber,
bool  overwrite,
bool  is_heap 
)

Definition at line 175 of file bufpage.c.

References elog, ereport, errcode(), errmsg(), ItemIdHasStorage, ItemIdIsUsed, ItemIdSetNormal, MAXALIGN, MaxHeapTuplesPerPage, memmove, OffsetNumberIsValid, OffsetNumberNext, PageClearHasFreeLinePointers, PageGetItemId, PageGetMaxOffsetNumber, PageHasFreeLinePointers, PANIC, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, SizeOfPageHeaderData, and WARNING.

Referenced by _bt_newroot(), _bt_pgaddtup(), _bt_restore_page(), _bt_sortaddtup(), _bt_split(), _hash_pgaddtup(), addLeafTuple(), addOrReplaceTuple(), btree_xlog_insert(), btree_xlog_split(), doPickSplit(), entryPlaceToPage(), entrySplitPage(), ginEntryFillRoot(), ginHeapTupleFastInsert(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginVacuumEntryPage(), gistfillbuffer(), gistplacetopage(), gistRedoPageUpdateRecord(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), raw_heap_insert(), RelationPutHeapTuple(), seq_redo(), spgAddNodeAction(), SpGistPageAddNewItem(), spgPageIndexMultiDelete(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), spgSplitNodeAction(), and writeListPage().

{
    PageHeader  phdr = (PageHeader) page;
    Size        alignedSize;
    int         lower;
    int         upper;
    ItemId      itemId;
    OffsetNumber limit;
    bool        needshuffle = false;

    /*
     * Be wary about corrupted page pointers
     */
    if (phdr->pd_lower < SizeOfPageHeaderData ||
        phdr->pd_lower > phdr->pd_upper ||
        phdr->pd_upper > phdr->pd_special ||
        phdr->pd_special > BLCKSZ)
        ereport(PANIC,
                (errcode(ERRCODE_DATA_CORRUPTED),
                 errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
                        phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));

    /*
     * Select offsetNumber to place the new item at
     */
    limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));

    /* was offsetNumber passed in? */
    if (OffsetNumberIsValid(offsetNumber))
    {
        /* yes, check it */
        if (overwrite)
        {
            if (offsetNumber < limit)
            {
                itemId = PageGetItemId(phdr, offsetNumber);
                if (ItemIdIsUsed(itemId) || ItemIdHasStorage(itemId))
                {
                    elog(WARNING, "will not overwrite a used ItemId");
                    return InvalidOffsetNumber;
                }
            }
        }
        else
        {
            if (offsetNumber < limit)
                needshuffle = true;     /* need to move existing linp's */
        }
    }
    else
    {
        /* offsetNumber was not passed in, so find a free slot */
        /* if no free slot, we'll put it at limit (1st open slot) */
        if (PageHasFreeLinePointers(phdr))
        {
            /*
             * Look for "recyclable" (unused) ItemId.  We check for no storage
             * as well, just to be paranoid --- unused items should never have
             * storage.
             */
            for (offsetNumber = 1; offsetNumber < limit; offsetNumber++)
            {
                itemId = PageGetItemId(phdr, offsetNumber);
                if (!ItemIdIsUsed(itemId) && !ItemIdHasStorage(itemId))
                    break;
            }
            if (offsetNumber >= limit)
            {
                /* the hint is wrong, so reset it */
                PageClearHasFreeLinePointers(phdr);
            }
        }
        else
        {
            /* don't bother searching if hint says there's no free slot */
            offsetNumber = limit;
        }
    }

    if (offsetNumber > limit)
    {
        elog(WARNING, "specified item offset is too large");
        return InvalidOffsetNumber;
    }

    if (is_heap && offsetNumber > MaxHeapTuplesPerPage)
    {
        elog(WARNING, "can't put more than MaxHeapTuplesPerPage items in a heap page");
        return InvalidOffsetNumber;
    }

    /*
     * Compute new lower and upper pointers for page, see if it'll fit.
     *
     * Note: do arithmetic as signed ints, to avoid mistakes if, say,
     * alignedSize > pd_upper.
     */
    if (offsetNumber == limit || needshuffle)
        lower = phdr->pd_lower + sizeof(ItemIdData);
    else
        lower = phdr->pd_lower;

    alignedSize = MAXALIGN(size);

    upper = (int) phdr->pd_upper - (int) alignedSize;

    if (lower > upper)
        return InvalidOffsetNumber;

    /*
     * OK to insert the item.  First, shuffle the existing pointers if needed.
     */
    itemId = PageGetItemId(phdr, offsetNumber);

    if (needshuffle)
        memmove(itemId + 1, itemId,
                (limit - offsetNumber) * sizeof(ItemIdData));

    /* set the item pointer */
    ItemIdSetNormal(itemId, upper, size);

    /* copy the item's data onto the page */
    memcpy((char *) page + upper, item, size);

    /* adjust page header */
    phdr->pd_lower = (LocationIndex) lower;
    phdr->pd_upper = (LocationIndex) upper;

    return offsetNumber;
}

Size PageGetExactFreeSpace ( Page  page  ) 

Definition at line 565 of file bufpage.c.

Referenced by _bt_findsplitloc(), allocNewBuffer(), doPickSplit(), ginHeapTupleFastInsert(), spgAddNodeAction(), SpGistGetBuffer(), SpGistPageAddNewItem(), SpGistSetLastUsedPage(), and writeListPage().

{
    int         space;

    /*
     * Use signed arithmetic here so that we behave sensibly if pd_lower >
     * pd_upper.
     */
    space = (int) ((PageHeader) page)->pd_upper -
        (int) ((PageHeader) page)->pd_lower;

    if (space < 0)
        return 0;

    return (Size) space;
}

Size PageGetFreeSpace ( Page  page  ) 

Definition at line 541 of file bufpage.c.

Referenced by _bt_buildadd(), _bt_findinsertloc(), _bt_insertonpg(), _hash_doinsert(), _hash_splitbucket(), _hash_squeezebucket(), entryIsEnoughSpace(), GetBTPageStatistics(), gistnospace(), PageGetHeapFreeSpace(), pgstat_index_page(), and pgstatindex().

{
    int         space;

    /*
     * Use signed arithmetic here so that we behave sensibly if pd_lower >
     * pd_upper.
     */
    space = (int) ((PageHeader) page)->pd_upper -
        (int) ((PageHeader) page)->pd_lower;

    if (space < (int) sizeof(ItemIdData))
        return 0;
    space -= sizeof(ItemIdData);

    return (Size) space;
}

Size PageGetHeapFreeSpace ( Page  page  ) 

Definition at line 598 of file bufpage.c.

References FirstOffsetNumber, ItemIdIsUsed, MaxHeapTuplesPerPage, OffsetNumberNext, PageGetFreeSpace(), PageGetItemId, PageGetMaxOffsetNumber, and PageHasFreeLinePointers.

Referenced by heap_multi_insert(), heap_page_prune_opt(), heap_update(), heap_xlog_clean(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_heap(), pgstat_heap(), raw_heap_insert(), and RelationGetBufferForTuple().

{
    Size        space;

    space = PageGetFreeSpace(page);
    if (space > 0)
    {
        OffsetNumber offnum,
                    nline;

        /*
         * Are there already MaxHeapTuplesPerPage line pointers in the page?
         */
        nline = PageGetMaxOffsetNumber(page);
        if (nline >= MaxHeapTuplesPerPage)
        {
            if (PageHasFreeLinePointers((PageHeader) page))
            {
                /*
                 * Since this is just a hint, we must confirm that there is
                 * indeed a free line pointer
                 */
                for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
                {
                    ItemId      lp = PageGetItemId(page, offnum);

                    if (!ItemIdIsUsed(lp))
                        break;
                }

                if (offnum > nline)
                {
                    /*
                     * The hint is wrong, but we can't clear it here since we
                     * don't have the ability to mark the page dirty.
                     */
                    space = 0;
                }
            }
            else
            {
                /*
                 * Although the hint might be wrong, PageAddItem will believe
                 * it anyway, so we must believe it too.
                 */
                space = 0;
            }
        }
    }
    return space;
}

Page PageGetTempPage ( Page  page  ) 

Definition at line 317 of file bufpage.c.

References PageGetPageSize, and palloc().

Referenced by _bt_split().

{
    Size        pageSize;
    Page        temp;

    pageSize = PageGetPageSize(page);
    temp = (Page) palloc(pageSize);

    return temp;
}

Page PageGetTempPageCopy ( Page  page  ) 

Definition at line 334 of file bufpage.c.

References PageGetPageSize, and palloc().

Referenced by dataSplitPage(), entrySplitPage(), and ginVacuumEntryPage().

{
    Size        pageSize;
    Page        temp;

    pageSize = PageGetPageSize(page);
    temp = (Page) palloc(pageSize);

    memcpy(temp, page, pageSize);

    return temp;
}

Page PageGetTempPageCopySpecial ( Page  page  ) 

Definition at line 354 of file bufpage.c.

References PageGetPageSize, PageGetSpecialPointer, PageGetSpecialSize, PageInit(), and palloc().

Referenced by gistplacetopage().

{
    Size        pageSize;
    Page        temp;

    pageSize = PageGetPageSize(page);
    temp = (Page) palloc(pageSize);

    PageInit(temp, pageSize, PageGetSpecialSize(page));
    memcpy(PageGetSpecialPointer(temp),
           PageGetSpecialPointer(page),
           PageGetSpecialSize(page));

    return temp;
}

void PageIndexMultiDelete ( Page  page,
OffsetNumber itemnos,
int  nitems 
)

Definition at line 765 of file bufpage.c.

References itemIdSortData::alignedlen, Assert, elog, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, itemIdSortData::itemoff, itemoffcompare(), ItemIdData::lp_off, MAXALIGN, memmove, itemIdSortData::offsetindex, OffsetNumberNext, itemIdSortData::olditemid, PageGetItemId, PageGetMaxOffsetNumber, PageIndexTupleDelete(), palloc(), PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, pfree(), qsort, and SizeOfPageHeaderData.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _hash_splitbucket(), _hash_squeezebucket(), btree_xlog_delete(), btree_xlog_split(), btree_xlog_vacuum(), ginRedoVacuumPage(), hashbulkdelete(), spgPageIndexMultiDelete(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().

{
    PageHeader  phdr = (PageHeader) page;
    Offset      pd_lower = phdr->pd_lower;
    Offset      pd_upper = phdr->pd_upper;
    Offset      pd_special = phdr->pd_special;
    itemIdSort  itemidbase,
                itemidptr;
    ItemId      lp;
    int         nline,
                nused;
    int         i;
    Size        totallen;
    Offset      upper;
    Size        size;
    unsigned    offset;
    int         nextitm;
    OffsetNumber offnum;

    /*
     * If there aren't very many items to delete, then retail
     * PageIndexTupleDelete is the best way.  Delete the items in reverse
     * order so we don't have to think about adjusting item numbers for
     * previous deletions.
     *
     * TODO: tune the magic number here
     */
    if (nitems <= 2)
    {
        while (--nitems >= 0)
            PageIndexTupleDelete(page, itemnos[nitems]);
        return;
    }

    /*
     * As with PageRepairFragmentation, paranoia seems justified.
     */
    if (pd_lower < SizeOfPageHeaderData ||
        pd_lower > pd_upper ||
        pd_upper > pd_special ||
        pd_special > BLCKSZ ||
        pd_special != MAXALIGN(pd_special))
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED),
                 errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
                        pd_lower, pd_upper, pd_special)));

    /*
     * Scan the item pointer array and build a list of just the ones we are
     * going to keep.  Notice we do not modify the page yet, since we are
     * still validity-checking.
     */
    nline = PageGetMaxOffsetNumber(page);
    itemidbase = (itemIdSort) palloc(sizeof(itemIdSortData) * nline);
    itemidptr = itemidbase;
    totallen = 0;
    nused = 0;
    nextitm = 0;
    for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
    {
        lp = PageGetItemId(page, offnum);
        Assert(ItemIdHasStorage(lp));
        size = ItemIdGetLength(lp);
        offset = ItemIdGetOffset(lp);
        if (offset < pd_upper ||
            (offset + size) > pd_special ||
            offset != MAXALIGN(offset))
            ereport(ERROR,
                    (errcode(ERRCODE_DATA_CORRUPTED),
                     errmsg("corrupted item pointer: offset = %u, size = %u",
                            offset, (unsigned int) size)));

        if (nextitm < nitems && offnum == itemnos[nextitm])
        {
            /* skip item to be deleted */
            nextitm++;
        }
        else
        {
            itemidptr->offsetindex = nused;     /* where it will go */
            itemidptr->itemoff = offset;
            itemidptr->olditemid = *lp;
            itemidptr->alignedlen = MAXALIGN(size);
            totallen += itemidptr->alignedlen;
            itemidptr++;
            nused++;
        }
    }

    /* this will catch invalid or out-of-order itemnos[] */
    if (nextitm != nitems)
        elog(ERROR, "incorrect index offsets supplied");

    if (totallen > (Size) (pd_special - pd_lower))
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED),
               errmsg("corrupted item lengths: total %u, available space %u",
                      (unsigned int) totallen, pd_special - pd_lower)));

    /* sort itemIdSortData array into decreasing itemoff order */
    qsort((char *) itemidbase, nused, sizeof(itemIdSortData),
          itemoffcompare);

    /* compactify page and install new itemids */
    upper = pd_special;

    for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++)
    {
        lp = PageGetItemId(page, itemidptr->offsetindex + 1);
        upper -= itemidptr->alignedlen;
        memmove((char *) page + upper,
                (char *) page + itemidptr->itemoff,
                itemidptr->alignedlen);
        *lp = itemidptr->olditemid;
        lp->lp_off = upper;
    }

    phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
    phdr->pd_upper = upper;

    pfree(itemidbase);
}

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offset 
)

Definition at line 659 of file bufpage.c.

References Assert, elog, ereport, errcode(), errmsg(), ERROR, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_off, MAXALIGN, memmove, PageGetItemId, PageGetMaxOffsetNumber, PageIsEmpty, PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, and SizeOfPageHeaderData.

Referenced by _bt_pagedel(), addLeafTuple(), addOrReplaceTuple(), btree_xlog_delete_page(), entryPreparePage(), ginRedoInsert(), ginVacuumEntryPage(), gistbulkdelete(), gistplacetopage(), gistRedoPageUpdateRecord(), PageIndexMultiDelete(), spgAddNodeAction(), SpGistPageAddNewItem(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), and spgSplitNodeAction().

{
    PageHeader  phdr = (PageHeader) page;
    char       *addr;
    ItemId      tup;
    Size        size;
    unsigned    offset;
    int         nbytes;
    int         offidx;
    int         nline;

    /*
     * As with PageRepairFragmentation, paranoia seems justified.
     */
    if (phdr->pd_lower < SizeOfPageHeaderData ||
        phdr->pd_lower > phdr->pd_upper ||
        phdr->pd_upper > phdr->pd_special ||
        phdr->pd_special > BLCKSZ)
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED),
                 errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
                        phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));

    nline = PageGetMaxOffsetNumber(page);
    if ((int) offnum <= 0 || (int) offnum > nline)
        elog(ERROR, "invalid index offnum: %u", offnum);

    /* change offset number to offset index */
    offidx = offnum - 1;

    tup = PageGetItemId(page, offnum);
    Assert(ItemIdHasStorage(tup));
    size = ItemIdGetLength(tup);
    offset = ItemIdGetOffset(tup);

    if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
        offset != MAXALIGN(offset) || size != MAXALIGN(size))
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED),
                 errmsg("corrupted item pointer: offset = %u, size = %u",
                        offset, (unsigned int) size)));

    /*
     * First, we want to get rid of the pd_linp entry for the index tuple. We
     * copy all subsequent linp's back one slot in the array. We don't use
     * PageGetItemId, because we are manipulating the _array_, not individual
     * linp's.
     */
    nbytes = phdr->pd_lower -
        ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);

    if (nbytes > 0)
        memmove((char *) &(phdr->pd_linp[offidx]),
                (char *) &(phdr->pd_linp[offidx + 1]),
                nbytes);

    /*
     * Now move everything between the old upper bound (beginning of tuple
     * space) and the beginning of the deleted tuple forward, so that space in
     * the middle of the page is left free.  If we've just deleted the tuple
     * at the beginning of tuple space, then there's no need to do the copy
     * (and bcopy on some architectures SEGV's if asked to move zero bytes).
     */

    /* beginning of tuple space */
    addr = (char *) page + phdr->pd_upper;

    if (offset > phdr->pd_upper)
        memmove(addr + size, addr, (int) (offset - phdr->pd_upper));

    /* adjust free space boundary pointers */
    phdr->pd_upper += size;
    phdr->pd_lower -= sizeof(ItemIdData);

    /*
     * Finally, we need to adjust the linp entries that remain.
     *
     * Anything that used to be before the deleted tuple's data was moved
     * forward by the size of the deleted tuple.
     */
    if (!PageIsEmpty(page))
    {
        int         i;

        nline--;                /* there's one less than when we started */
        for (i = 1; i <= nline; i++)
        {
            ItemId      ii = PageGetItemId(phdr, i);

            Assert(ItemIdHasStorage(ii));
            if (ItemIdGetOffset(ii) <= offset)
                ii->lp_off += size;
        }
    }
}

void PageInit ( Page  page,
Size  pageSize,
Size  specialSize 
)

Definition at line 40 of file bufpage.c.

References Assert, MAXALIGN, MemSet, PageSetPageSizeAndVersion, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PG_PAGE_LAYOUT_VERSION, and SizeOfPageHeaderData.

Referenced by _bt_pageinit(), _hash_pageinit(), fill_seq_with_data(), fsm_extend(), fsm_readbuf(), GinInitPage(), GISTInitBuffer(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), PageGetTempPageCopySpecial(), raw_heap_insert(), RelationGetBufferForTuple(), seq_redo(), SetMatViewToPopulated(), SpGistInitPage(), vm_extend(), vm_readbuf(), and XLogRecordPageWithFreeSpace().

{
    PageHeader  p = (PageHeader) page;

    specialSize = MAXALIGN(specialSize);

    Assert(pageSize == BLCKSZ);
    Assert(pageSize > specialSize + SizeOfPageHeaderData);

    /* Make sure all fields of page are zero, as well as unused space */
    MemSet(p, 0, pageSize);

    p->pd_flags = 0;
    p->pd_lower = SizeOfPageHeaderData;
    p->pd_upper = pageSize - specialSize;
    p->pd_special = pageSize - specialSize;
    PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION);
    /* p->pd_prune_xid = InvalidTransactionId;      done by above MemSet */
}

bool PageIsVerified ( Page  page,
BlockNumber  blkno 
)

Definition at line 80 of file bufpage.c.

References DataChecksumsEnabled(), ereport, errmsg(), i, ignore_checksum_failure, MAXALIGN, PageCalcChecksum16(), PageIsNew, PageHeaderData::pd_checksum, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PD_VALID_FLAG_BITS, and WARNING.

Referenced by copy_relation_data(), and ReadBuffer_common().

{
    PageHeader  p = (PageHeader) page;
    char       *pagebytes;
    int         i;
    bool        checksum_failure = false;
    bool        header_sane = false;
    bool        all_zeroes = false;
    uint16      checksum = 0;

    /*
     * Don't verify page data unless the page passes basic non-zero test
     */
    if (!PageIsNew(page))
    {
        if (DataChecksumsEnabled())
        {
            checksum = PageCalcChecksum16(page, blkno);

            if (checksum != p->pd_checksum)
                checksum_failure = true;
        }

        /*
         * The following checks don't prove the header is correct,
         * only that it looks sane enough to allow into the buffer pool.
         * Later usage of the block can still reveal problems,
         * which is why we offer the checksum option.
         */
        if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
             p->pd_lower <= p->pd_upper &&
             p->pd_upper <= p->pd_special &&
             p->pd_special <= BLCKSZ &&
             p->pd_special == MAXALIGN(p->pd_special))
            header_sane = true;

        if (header_sane && !checksum_failure)
            return true;
    }

    /* Check all-zeroes case */
    all_zeroes = true;
    pagebytes = (char *) page;
    for (i = 0; i < BLCKSZ; i++)
    {
        if (pagebytes[i] != 0)
        {
            all_zeroes = false;
            break;
        }
    }

    if (all_zeroes)
        return true;

    /*
     * Throw a WARNING if the checksum fails, but only after we've checked for
     * the all-zeroes case.
     */
    if (checksum_failure)
    {
        ereport(WARNING,
                (ERRCODE_DATA_CORRUPTED,
                 errmsg("page verification failed, calculated checksum %u but expected %u",
                        checksum, p->pd_checksum)));

        if (header_sane && ignore_checksum_failure)
            return true;
    }

    return false;
}

void PageRepairFragmentation ( Page  page  ) 

Definition at line 417 of file bufpage.c.

References itemIdSortData::alignedlen, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdIsUsed, ItemIdSetUnused, itemIdSortData::itemoff, itemoffcompare(), ItemIdData::lp_off, MAXALIGN, memmove, itemIdSortData::offsetindex, PageClearHasFreeLinePointers, PageGetItemId, PageGetMaxOffsetNumber, PageSetHasFreeLinePointers, palloc(), pfree(), qsort, and SizeOfPageHeaderData.

Referenced by heap_page_prune_execute(), and lazy_vacuum_page().

{
    Offset      pd_lower = ((PageHeader) page)->pd_lower;
    Offset      pd_upper = ((PageHeader) page)->pd_upper;
    Offset      pd_special = ((PageHeader) page)->pd_special;
    itemIdSort  itemidbase,
                itemidptr;
    ItemId      lp;
    int         nline,
                nstorage,
                nunused;
    int         i;
    Size        totallen;
    Offset      upper;

    /*
     * It's worth the trouble to be more paranoid here than in most places,
     * because we are about to reshuffle data in (what is usually) a shared
     * disk buffer.  If we aren't careful then corrupted pointers, lengths,
     * etc could cause us to clobber adjacent disk buffers, spreading the data
     * loss further.  So, check everything.
     */
    if (pd_lower < SizeOfPageHeaderData ||
        pd_lower > pd_upper ||
        pd_upper > pd_special ||
        pd_special > BLCKSZ ||
        pd_special != MAXALIGN(pd_special))
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED),
                 errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
                        pd_lower, pd_upper, pd_special)));

    nline = PageGetMaxOffsetNumber(page);
    nunused = nstorage = 0;
    for (i = FirstOffsetNumber; i <= nline; i++)
    {
        lp = PageGetItemId(page, i);
        if (ItemIdIsUsed(lp))
        {
            if (ItemIdHasStorage(lp))
                nstorage++;
        }
        else
        {
            /* Unused entries should have lp_len = 0, but make sure */
            ItemIdSetUnused(lp);
            nunused++;
        }
    }

    if (nstorage == 0)
    {
        /* Page is completely empty, so just reset it quickly */
        ((PageHeader) page)->pd_upper = pd_special;
    }
    else
    {                           /* nstorage != 0 */
        /* Need to compact the page the hard way */
        itemidbase = (itemIdSort) palloc(sizeof(itemIdSortData) * nstorage);
        itemidptr = itemidbase;
        totallen = 0;
        for (i = 0; i < nline; i++)
        {
            lp = PageGetItemId(page, i + 1);
            if (ItemIdHasStorage(lp))
            {
                itemidptr->offsetindex = i;
                itemidptr->itemoff = ItemIdGetOffset(lp);
                if (itemidptr->itemoff < (int) pd_upper ||
                    itemidptr->itemoff >= (int) pd_special)
                    ereport(ERROR,
                            (errcode(ERRCODE_DATA_CORRUPTED),
                             errmsg("corrupted item pointer: %u",
                                    itemidptr->itemoff)));
                itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
                totallen += itemidptr->alignedlen;
                itemidptr++;
            }
        }

        if (totallen > (Size) (pd_special - pd_lower))
            ereport(ERROR,
                    (errcode(ERRCODE_DATA_CORRUPTED),
               errmsg("corrupted item lengths: total %u, available space %u",
                      (unsigned int) totallen, pd_special - pd_lower)));

        /* sort itemIdSortData array into decreasing itemoff order */
        qsort((char *) itemidbase, nstorage, sizeof(itemIdSortData),
              itemoffcompare);

        /* compactify page */
        upper = pd_special;

        for (i = 0, itemidptr = itemidbase; i < nstorage; i++, itemidptr++)
        {
            lp = PageGetItemId(page, itemidptr->offsetindex + 1);
            upper -= itemidptr->alignedlen;
            memmove((char *) page + upper,
                    (char *) page + itemidptr->itemoff,
                    itemidptr->alignedlen);
            lp->lp_off = upper;
        }

        ((PageHeader) page)->pd_upper = upper;

        pfree(itemidbase);
    }

    /* Set hint bit for PageAddItem */
    if (nunused > 0)
        PageSetHasFreeLinePointers(page);
    else
        PageClearHasFreeLinePointers(page);
}

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 376 of file bufpage.c.

References PageGetPageSize, and pfree().

Referenced by _bt_split(), ginbulkdelete(), ginInsertValue(), and gistplacetopage().

{
    Size        pageSize;

    pageSize = PageGetPageSize(tempPage);
    memcpy((char *) oldPage, (char *) tempPage, pageSize);

    pfree(tempPage);
}

char* PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 901 of file bufpage.c.

References DataChecksumsEnabled(), pageCopy, PageIsNew, and PageSetChecksumInplace().

Referenced by FlushBuffer().

{
    if (PageIsNew(page) || !DataChecksumsEnabled())
        return (char *) page;

    /*
     * We make a copy iff we need to calculate a checksum because other
     * backends may set hint bits on this page while we write, which
     * would mean the checksum differs from the page contents. It doesn't
     * matter if we include or exclude hints during the copy, as long
     * as we write a valid page and associated checksum.
     */
    memcpy((char *) pageCopy, (char *) page, BLCKSZ);
    PageSetChecksumInplace(pageCopy, blkno);
    return (char *) pageCopy;
}

void PageSetChecksumInplace ( Page  page,
BlockNumber  blkno 
)