blob: c011cd6f436cdeb53f1b3a9cca20dacbf1078bce [file] [log] [blame]
/*
* brin_page.h
* Prototypes and definitions for BRIN page layouts
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/include/access/brin_page.h
*
* NOTES
*
* These structs should really be private to specific BRIN files, but it's
* useful to have them here so that they can be used by pageinspect and similar
* tools.
*/
#ifndef BRIN_PAGE_H
#define BRIN_PAGE_H
#include "appendonlywriter.h"
#include "storage/block.h"
#include "storage/itemptr.h"
/*
* Special area of BRIN pages.
*
* We define it in this odd way so that it always occupies the last
* MAXALIGN-sized element of each page.
*/
typedef struct BrinSpecialSpace
{
BlockNumber logicalPageNum; /* AO/CO: 1-based logical page number */
BlockNumber nextRevmapPage; /* AO/CO: Only for revmap pages */
uint16 vector[MAXALIGN(1) / sizeof(uint16)];
} BrinSpecialSpace;
/*
* Make the page type be the last half-word in the page, for consumption by
* pg_filedump and similar utilities. We don't really care much about the
* position of the "flags" half-word, but it's simpler to apply a consistent
* rule to both.
*
* See comments above GinPageOpaqueData.
*/
#define BrinPageType(page) \
(((BrinSpecialSpace *) \
PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 1])
#define BrinPageFlags(page) \
(((BrinSpecialSpace *) \
PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 2])
/* GPDB: We maintain a chain of revmap pages for AO/CO tables */
#define BrinLogicalPageNum(page) \
(((BrinSpecialSpace *) \
PageGetSpecialPointer(page))->logicalPageNum)
#define BrinNextRevmapPage(page) \
(((BrinSpecialSpace *) \
PageGetSpecialPointer(page))->nextRevmapPage)
/* special space on all BRIN pages stores a "type" identifier */
#define BRIN_PAGETYPE_META 0xF091
#define BRIN_PAGETYPE_REVMAP 0xF092
#define BRIN_PAGETYPE_REGULAR 0xF093
#define BRIN_IS_META_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_META)
#define BRIN_IS_REVMAP_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REVMAP)
#define BRIN_IS_REGULAR_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REGULAR)
/* flags for BrinSpecialSpace */
#define BRIN_EVACUATE_PAGE (1 << 0)
/*
* GPDB: We maintain a 1-based logical page number in revmap pages. This number
* gives us a way to find revmap pages, given a logical block number. This
* number is relative within a block sequence and starts from 1, with 1
* representing all the heap blocks the 1st revmap page can contain. See
* HEAPBLK_TO_REVMAP_PAGENUM_AO() for more details. It is 1-based for
* convenience in routines such as revmap_extend_and_get_blkno_ao(), where a
* value of 0, can be used to represent the empty case.
*/
typedef BlockNumber LogicalPageNum;
#define InvalidLogicalPageNum (0)
/*
* GPDB: Bookkeeping for the head and tail of the revmap page chain maintained
* for AO/CO tables.
*/
typedef struct AOChainInfo {
/* the first and last revmap pages of a chain for each block sequence */
BlockNumber firstPage;
BlockNumber lastPage;
/* last logical revmap page number for each block sequence (1-based) */
LogicalPageNum lastLogicalPageNum;
} AOChainInfo;
/* Metapage definitions */
typedef struct BrinMetaPageData
{
uint32 brinMagic;
uint32 brinVersion;
BlockNumber pagesPerRange;
BlockNumber lastRevmapPage;
/* GPDB section to handle AO/CO tables */
bool isAO;
AOChainInfo aoChainInfo[MAX_AOREL_CONCURRENCY];
} BrinMetaPageData;
#define BRIN_CURRENT_VERSION 1
#define BRIN_META_MAGIC 0xA8109CFA
#define BRIN_METAPAGE_BLKNO 0
/* Definitions for revmap pages */
typedef struct RevmapContents
{
/*
* This array will fill all available space on the page. It should be
* declared [FLEXIBLE_ARRAY_MEMBER], but for some reason you can't do that
* in an otherwise-empty struct.
*/
ItemPointerData rm_tids[1];
} RevmapContents;
#define REVMAP_CONTENT_SIZE \
(BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \
offsetof(RevmapContents, rm_tids) - \
MAXALIGN(sizeof(BrinSpecialSpace)))
/* max num of items in the array */
#define REVMAP_PAGE_MAXITEMS \
(REVMAP_CONTENT_SIZE / sizeof(ItemPointerData))
#endif /* BRIN_PAGE_H */