bufpage.h 7.6 KB
Newer Older
1 2 3 4 5 6 7 8
/*-------------------------------------------------------------------------
 *
 * bufpage.h--
 *    Standard POSTGRES buffer page definitions.
 *
 *
 * Copyright (c) 1994, Regents of the University of California
 *
9
 * $Id: bufpage.h,v 1.2 1996/10/18 07:39:07 vadim Exp $
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
 *
 *-------------------------------------------------------------------------
 */
#ifndef	BUFPAGE_H
#define BUFPAGE_H

#include "c.h"
#include "machine.h"		/* for BLCKSZ */

#include "storage/buf.h"
#include "storage/item.h"
#include "storage/itemid.h"
#include "storage/itemptr.h"

/*
 * a postgres disk page is an abstraction layered on top of a postgres
 * disk block (which is simply a unit of i/o, see block.h).
 *
 * specifically, while a disk block can be unformatted, a postgres
 * disk page is always a slotted page of the form:
 *
 * +----------------+---------------------------------+
 * | PageHeaderData | linp0 linp1 linp2 ...           |
 * +-----------+----+---------------------------------+
 * | ... linpN |                                      |
 * +-----------+--------------------------------------+
 * |           ^ pd_lower                             |
 * |                                                  |
 * |             v pd_upper                           |
 * +-------------+------------------------------------+
 * |             | tupleN ...                         |
 * +-------------+------------------+-----------------+
 * |       ... tuple2 tuple1 tuple0 | "special space" |
 * +--------------------------------+-----------------+
 *                                  ^ pd_special
 *
 * a page is full when nothing can be added between pd_lower and
 * pd_upper.
 *
 * all blocks written out by an access method must be disk pages.
 *
 * EXCEPTIONS:
 *
 * obviously, a page is not formatted before it is initialized with by
 * a call to PageInit.
 *
 * the contents of the special pg_variable/pg_time/pg_log tables are
 * raw disk blocks with special formats.  these are the only "access
 * methods" that need not write disk pages.
 *
 * NOTES:
 *
 * linp0..N form an ItemId array.  ItemPointers point into this array
 * rather than pointing directly to a tuple.
 *
 * tuple0..N are added "backwards" on the page.  because a tuple's
 * ItemPointer points to its ItemId entry rather than its actual
 * byte-offset position, tuples can be physically shuffled on a page
 * whenever the need arises.
 *
 * AM-generic per-page information is kept in the pd_opaque field of
 * the PageHeaderData.  (this is currently only the page size.)
 * AM-specific per-page data is kept in the area marked "special
 * space"; each AM has an "opaque" structure defined somewhere that is
 * stored as the page trailer.  an access method should always
 * initialize its pages with PageInit and then set its own opaque
 * fields.
 */
typedef Pointer	Page;

/*
 * PageIsValid --
 *	True iff page is valid.
 */
#define	PageIsValid(page) PointerIsValid(page)


/*
 * location (byte offset) within a page.
 *
 * note that this is actually limited to 2^13 because we have limited
 * ItemIdData.lp_off and ItemIdData.lp_len to 13 bits (see itemid.h).
 */
typedef uint16	LocationIndex;


/*
 * space management information generic to any page
 *
 *	od_pagesize	- size in bytes.
 *			  in reality, we need at least 64B to fit the 
 *			  page header, opaque space and a minimal tuple;
 *			  on the high end, we can only support pages up
 *			  to 8KB because lp_off/lp_len are 13 bits.
 */
typedef struct OpaqueData {
    uint16 od_pagesize;
} OpaqueData;
    
typedef OpaqueData	*Opaque;


/*
 * disk page organization
 */
typedef struct PageHeaderData {
    LocationIndex	pd_lower;	/* offset to start of free space */
    LocationIndex	pd_upper;	/* offset to end of free space */
    LocationIndex	pd_special;	/* offset to start of special space */
    OpaqueData       	pd_opaque;	/* AM-generic information */
    ItemIdData		pd_linp[1];	/* line pointers */
} PageHeaderData;

typedef PageHeaderData	*PageHeader;

typedef enum {
    ShufflePageManagerMode,
    OverwritePageManagerMode
} PageManagerMode;

/* ----------------
 *	misc support macros
 * ----------------
 */

/*
 * XXX this is wrong -- ignores padding/alignment, variable page size,
 * AM-specific opaque space at the end of the page (as in btrees), ...
 * however, it at least serves as an upper bound for heap pages.
 */
#define MAXTUPLEN	(BLCKSZ - sizeof (PageHeaderData))

/* ----------------------------------------------------------------
 *			page support macros
 * ----------------------------------------------------------------
 */
/*
 * PageIsValid -- This is defined in page.h.
 */

/*
 * PageIsUsed --
 *	True iff the page size is used.
 *
 * Note:
 *	Assumes page is valid.
 */
#define PageIsUsed(page) \
    (AssertMacro(PageIsValid(page)) ? \
     ((bool) (((PageHeader) (page))->pd_lower != 0)) : false)

/*
 * PageIsEmpty --
 *	returns true iff no itemid has been allocated on the page
 */
#define PageIsEmpty(page) \
    (((PageHeader) (page))->pd_lower == \
     (sizeof(PageHeaderData) - sizeof(ItemIdData)) ? true : false)

169 170 171 172 173 174 175
/*
 * PageIsNew -- 
 *	returns true iff page is not initialized (by PageInit)
 */

#define PageIsNew(page)	(((PageHeader) (page))->pd_upper == 0)

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/*
 * PageGetItemId --
 *	Returns an item identifier of a page.
 */
#define PageGetItemId(page, offsetNumber) \
    ((ItemId) (&((PageHeader) (page))->pd_linp[(-1) + (offsetNumber)]))

/* ----------------
 *	macros to access opaque space
 * ----------------
 */

/*
 * PageSizeIsValid --
 *	True iff the page size is valid.
 *
 * XXX currently all page sizes are "valid" but we only actually
 *     use BLCKSZ.
 */
#define PageSizeIsValid(pageSize) 1

/*
 * PageGetPageSize --
 *	Returns the page size of a page.
 *
 * this can only be called on a formatted page (unlike
 * BufferGetPageSize, which can be called on an unformatted page).
 * however, it can be called on a page for which there is no buffer.
 */
#define PageGetPageSize(page) \
    ((Size) ((PageHeader) (page))->pd_opaque.od_pagesize)

/*
 * PageSetPageSize --
 *	Sets the page size of a page.
 */
#define PageSetPageSize(page, size) \
    ((PageHeader) (page))->pd_opaque.od_pagesize = (size)

/* ----------------
 *	page special data macros
 * ----------------
 */
/*
 * PageGetSpecialSize --
 *	Returns size of special space on a page.
 *
 * Note:
 *	Assumes page is locked.
 */
#define PageGetSpecialSize(page) \
    ((uint16) (PageGetPageSize(page) - ((PageHeader)page)->pd_special))

/*
 * PageGetSpecialPointer --
 *	Returns pointer to special space on a page.
 *
 * Note:
 *	Assumes page is locked.
 */
#define PageGetSpecialPointer(page) \
    (AssertMacro(PageIsValid(page)) ? \
     (char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
     : (char *) 0)

/* ----------------------------------------------------------------
 *	extern declarations
 * ----------------------------------------------------------------
 */

extern Size BufferGetPageSize(Buffer buffer);
extern Page BufferGetPage(Buffer buffer);
extern void PageInit(Page page, Size pageSize, Size specialSize);
extern Item PageGetItem(Page page, ItemId itemId);
extern OffsetNumber PageAddItem(Page page, Item item, Size size,
			 OffsetNumber offsetNumber, ItemIdFlags flags);
extern Page PageGetTempPage(Page page, Size specialSize);
extern void PageRestoreTempPage(Page tempPage, Page oldPage);
extern OffsetNumber PageGetMaxOffsetNumber(Page page);
extern void PageRepairFragmentation(Page page);
extern Size PageGetFreeSpace(Page page);
extern void PageManagerModeSet(PageManagerMode mode);
extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
extern void PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr,
				       char *location, Size size);


#endif	/* BUFPAGE_H */