bufpage.h
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:8k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * bufpage.h
  4.  *   Standard POSTGRES buffer page definitions.
  5.  *
  6.  *
  7.  * Copyright (c) 1994, Regents of the University of California
  8.  *
  9.  * $Id: bufpage.h,v 1.23 1999/07/03 00:32:59 momjian Exp $
  10.  *
  11.  *-------------------------------------------------------------------------
  12.  */
  13. #ifndef BUFPAGE_H
  14. #define BUFPAGE_H
  15. #include <storage/off.h>
  16. #include <storage/itemid.h>
  17. #include <storage/item.h>
  18. #include <storage/buf.h>
  19. #include <storage/page.h>
  20. /*
  21.  * a postgres disk page is an abstraction layered on top of a postgres
  22.  * disk block (which is simply a unit of i/o, see block.h).
  23.  *
  24.  * specifically, while a disk block can be unformatted, a postgres
  25.  * disk page is always a slotted page of the form:
  26.  *
  27.  * +----------------+---------------------------------+
  28.  * | PageHeaderData | linp0 linp1 linp2 ...   |
  29.  * +-----------+----+---------------------------------+
  30.  * | ... linpN |   |
  31.  * +-----------+--------------------------------------+
  32.  * |    ^ pd_lower   |
  33.  * |   |
  34.  * |  v pd_upper   |
  35.  * +-------------+------------------------------------+
  36.  * |  | tupleN ...   |
  37.  * +-------------+------------------+-----------------+
  38.  * |    ... tuple2 tuple1 tuple0 | "special space" |
  39.  * +--------------------------------+-----------------+
  40.  * ^ pd_special
  41.  *
  42.  * a page is full when nothing can be added between pd_lower and
  43.  * pd_upper.
  44.  *
  45.  * all blocks written out by an access method must be disk pages.
  46.  *
  47.  * EXCEPTIONS:
  48.  *
  49.  * obviously, a page is not formatted before it is initialized with by
  50.  * a call to PageInit.
  51.  *
  52.  * the contents of the special pg_variable/pg_time/pg_log tables are
  53.  * raw disk blocks with special formats.  these are the only "access
  54.  * methods" that need not write disk pages.
  55.  *
  56.  * NOTES:
  57.  *
  58.  * linp0..N form an ItemId array.  ItemPointers point into this array
  59.  * rather than pointing directly to a tuple.
  60.  *
  61.  * tuple0..N are added "backwards" on the page.  because a tuple's
  62.  * ItemPointer points to its ItemId entry rather than its actual
  63.  * byte-offset position, tuples can be physically shuffled on a page
  64.  * whenever the need arises.
  65.  *
  66.  * AM-generic per-page information is kept in the pd_opaque field of
  67.  * the PageHeaderData. (this is currently only the page size.)
  68.  * AM-specific per-page data is kept in the area marked "special
  69.  * space"; each AM has an "opaque" structure defined somewhere that is
  70.  * stored as the page trailer. an access method should always
  71.  * initialize its pages with PageInit and then set its own opaque
  72.  * fields.
  73.  */
  74. /*
  75.  * PageIsValid
  76.  * True iff page is valid.
  77.  */
  78. #define PageIsValid(page) PointerIsValid(page)
  79. /*
  80.  * location (byte offset) within a page.
  81.  *
  82.  * note that this is actually limited to 2^13 because we have limited
  83.  * ItemIdData.lp_off and ItemIdData.lp_len to 13 bits (see itemid.h).
  84.  *
  85.  * uint16 is still valid, but the limit has been raised to 15 bits.
  86.  * 06 Jan 98 - darrenk
  87.  */
  88. typedef uint16 LocationIndex;
  89. /*
  90.  * space management information generic to any page
  91.  *
  92.  * od_pagesize - size in bytes.
  93.  *   in reality, we need at least 64B to fit the
  94.  *   page header, opaque space and a minimal tuple;
  95.  *   on the high end, we can only support pages up
  96.  *   to 8KB because lp_off/lp_len are 13 bits.
  97.  *
  98.  *   see above comment.  Now use 15 bits and pages
  99.  *   up to 32KB at your own risk.
  100.  */
  101. typedef struct OpaqueData
  102. {
  103. uint16 od_pagesize;
  104. } OpaqueData;
  105. typedef OpaqueData *Opaque;
  106. /*
  107.  * disk page organization
  108.  */
  109. typedef struct PageHeaderData
  110. {
  111. LocationIndex pd_lower; /* offset to start of free space */
  112. LocationIndex pd_upper; /* offset to end of free space */
  113. LocationIndex pd_special; /* offset to start of special space */
  114. OpaqueData pd_opaque; /* AM-generic information */
  115. ItemIdData pd_linp[1]; /* line pointers */
  116. } PageHeaderData;
  117. typedef PageHeaderData *PageHeader;
  118. typedef enum
  119. {
  120. ShufflePageManagerMode,
  121. OverwritePageManagerMode
  122. } PageManagerMode;
  123. /* ----------------------------------------------------------------
  124.  * page support macros
  125.  * ----------------------------------------------------------------
  126.  */
  127. /*
  128.  * PageIsValid -- This is defined in page.h.
  129.  */
  130. /*
  131.  * PageIsUsed
  132.  * True iff the page size is used.
  133.  *
  134.  * Note:
  135.  * Assumes page is valid.
  136.  */
  137. #define PageIsUsed(page) 
  138. AssertMacro(PageIsValid(page)), 
  139. ((bool) (((PageHeader) (page))->pd_lower != 0)) 
  140. )
  141. /*
  142.  * PageIsEmpty
  143.  * returns true iff no itemid has been allocated on the page
  144.  */
  145. #define PageIsEmpty(page) 
  146. (((PageHeader) (page))->pd_lower == 
  147.  (sizeof(PageHeaderData) - sizeof(ItemIdData)) ? true : false)
  148. /*
  149.  * PageIsNew
  150.  * returns true iff page is not initialized (by PageInit)
  151.  */
  152. #define PageIsNew(page) (((PageHeader) (page))->pd_upper == 0)
  153. /*
  154.  * PageGetItemId
  155.  * Returns an item identifier of a page.
  156.  */
  157. #define PageGetItemId(page, offsetNumber) 
  158. ((ItemId) (&((PageHeader) (page))->pd_linp[(-1) + (offsetNumber)]))
  159. /* ----------------
  160.  * macros to access opaque space
  161.  * ----------------
  162.  */
  163. /*
  164.  * PageSizeIsValid
  165.  * True iff the page size is valid.
  166.  *
  167.  * XXX currently all page sizes are "valid" but we only actually
  168.  *    use BLCKSZ.
  169.  *
  170.  * 01/06/98 Now does something useful. darrenk
  171.  *
  172.  */
  173. #define PageSizeIsValid(pageSize) ((pageSize) == BLCKSZ)
  174. /*
  175.  * PageGetPageSize
  176.  * Returns the page size of a page.
  177.  *
  178.  * this can only be called on a formatted page (unlike
  179.  * BufferGetPageSize, which can be called on an unformatted page).
  180.  * however, it can be called on a page for which there is no buffer.
  181.  */
  182. #define PageGetPageSize(page) 
  183. ((Size) ((PageHeader) (page))->pd_opaque.od_pagesize)
  184. /*
  185.  * PageSetPageSize
  186.  * Sets the page size of a page.
  187.  */
  188. #define PageSetPageSize(page, size) 
  189. ((PageHeader) (page))->pd_opaque.od_pagesize = (size)
  190. /* ----------------
  191.  * page special data macros
  192.  * ----------------
  193.  */
  194. /*
  195.  * PageGetSpecialSize
  196.  * Returns size of special space on a page.
  197.  *
  198.  * Note:
  199.  * Assumes page is locked.
  200.  */
  201. #define PageGetSpecialSize(page) 
  202. ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
  203. /*
  204.  * PageGetSpecialPointer
  205.  * Returns pointer to special space on a page.
  206.  *
  207.  * Note:
  208.  * Assumes page is locked.
  209.  */
  210. #define PageGetSpecialPointer(page) 
  211. AssertMacro(PageIsValid(page)), 
  212. (char *) ((char *) (page) + ((PageHeader) (page))->pd_special) 
  213. )
  214. /*
  215.  * PageGetItem
  216.  * Retrieves an item on the given page.
  217.  *
  218.  * Note:
  219.  * This does change the status of any of the resources passed.
  220.  * The semantics may change in the future.
  221.  */
  222. #define PageGetItem(page, itemId) 
  223. AssertMacro(PageIsValid(page)), 
  224. AssertMacro((itemId)->lp_flags & LP_USED), 
  225. (Item)(((char *)(page)) + (itemId)->lp_off) 
  226. )
  227. /*
  228.  * BufferGetPageSize
  229.  * Returns the page size within a buffer.
  230.  *
  231.  * Notes:
  232.  * Assumes buffer is valid.
  233.  *
  234.  * The buffer can be a raw disk block and need not contain a valid
  235.  * (formatted) disk page.
  236.  */
  237. /* XXX dig out of buffer descriptor */
  238. #define BufferGetPageSize(buffer) 
  239. AssertMacro(BufferIsValid(buffer)), 
  240. (Size)BLCKSZ 
  241. )
  242. /*
  243.  * BufferGetPage
  244.  * Returns the page associated with a buffer.
  245.  */
  246. #define BufferGetPage(buffer) ((Page)BufferGetBlock(buffer))
  247. /*
  248.  * PageGetMaxOffsetNumber
  249.  * Returns the maximum offset number used by the given page.
  250.  *
  251.  * NOTE: The offset is invalid if the page is non-empty.
  252.  * Test whether PageIsEmpty before calling this routine
  253.  * and/or using its return value.
  254.  */
  255. #define PageGetMaxOffsetNumber(page) 
  256. (((PageHeader) (page))->pd_lower - 
  257. (sizeof(PageHeaderData) - sizeof(ItemIdData))) 
  258. / sizeof(ItemIdData) 
  259. )
  260. /* ----------------------------------------------------------------
  261.  * extern declarations
  262.  * ----------------------------------------------------------------
  263.  */
  264. extern void PageInit(Page page, Size pageSize, Size specialSize);
  265. extern OffsetNumber PageAddItem(Page page, Item item, Size size,
  266. OffsetNumber offsetNumber, ItemIdFlags flags);
  267. extern Page PageGetTempPage(Page page, Size specialSize);
  268. extern void PageRestoreTempPage(Page tempPage, Page oldPage);
  269. extern void PageRepairFragmentation(Page page);
  270. extern Size PageGetFreeSpace(Page page);
  271. extern void PageManagerModeSet(PageManagerMode mode);
  272. extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
  273. #endif  /* BUFPAGE_H */