| 1 | /* |
| 2 | * brin_page.h |
| 3 | * Prototypes and definitions for BRIN page layouts |
| 4 | * |
| 5 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 6 | * Portions Copyright (c) 1994, Regents of the University of California |
| 7 | * |
| 8 | * IDENTIFICATION |
| 9 | * src/include/access/brin_page.h |
| 10 | * |
| 11 | * NOTES |
| 12 | * |
| 13 | * These structs should really be private to specific BRIN files, but it's |
| 14 | * useful to have them here so that they can be used by pageinspect and similar |
| 15 | * tools. |
| 16 | */ |
| 17 | #ifndef BRIN_PAGE_H |
| 18 | #define BRIN_PAGE_H |
| 19 | |
| 20 | #include "storage/block.h" |
| 21 | #include "storage/itemptr.h" |
| 22 | |
| 23 | /* |
| 24 | * Special area of BRIN pages. |
| 25 | * |
| 26 | * We define it in this odd way so that it always occupies the last |
| 27 | * MAXALIGN-sized element of each page. |
| 28 | */ |
| 29 | typedef struct BrinSpecialSpace |
| 30 | { |
| 31 | uint16 vector[MAXALIGN(1) / sizeof(uint16)]; |
| 32 | } BrinSpecialSpace; |
| 33 | |
| 34 | /* |
| 35 | * Make the page type be the last half-word in the page, for consumption by |
| 36 | * pg_filedump and similar utilities. We don't really care much about the |
| 37 | * position of the "flags" half-word, but it's simpler to apply a consistent |
| 38 | * rule to both. |
| 39 | * |
| 40 | * See comments above GinPageOpaqueData. |
| 41 | */ |
| 42 | #define BrinPageType(page) \ |
| 43 | (((BrinSpecialSpace *) \ |
| 44 | PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 1]) |
| 45 | |
| 46 | #define BrinPageFlags(page) \ |
| 47 | (((BrinSpecialSpace *) \ |
| 48 | PageGetSpecialPointer(page))->vector[MAXALIGN(1) / sizeof(uint16) - 2]) |
| 49 | |
| 50 | /* special space on all BRIN pages stores a "type" identifier */ |
| 51 | #define BRIN_PAGETYPE_META 0xF091 |
| 52 | #define BRIN_PAGETYPE_REVMAP 0xF092 |
| 53 | #define BRIN_PAGETYPE_REGULAR 0xF093 |
| 54 | |
| 55 | #define BRIN_IS_META_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_META) |
| 56 | #define BRIN_IS_REVMAP_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REVMAP) |
| 57 | #define BRIN_IS_REGULAR_PAGE(page) (BrinPageType(page) == BRIN_PAGETYPE_REGULAR) |
| 58 | |
| 59 | /* flags for BrinSpecialSpace */ |
| 60 | #define BRIN_EVACUATE_PAGE (1 << 0) |
| 61 | |
| 62 | |
| 63 | /* Metapage definitions */ |
| 64 | typedef struct BrinMetaPageData |
| 65 | { |
| 66 | uint32 brinMagic; |
| 67 | uint32 brinVersion; |
| 68 | BlockNumber pagesPerRange; |
| 69 | BlockNumber lastRevmapPage; |
| 70 | } BrinMetaPageData; |
| 71 | |
| 72 | #define BRIN_CURRENT_VERSION 1 |
| 73 | #define BRIN_META_MAGIC 0xA8109CFA |
| 74 | |
| 75 | #define BRIN_METAPAGE_BLKNO 0 |
| 76 | |
| 77 | /* Definitions for revmap pages */ |
| 78 | typedef struct RevmapContents |
| 79 | { |
| 80 | /* |
| 81 | * This array will fill all available space on the page. It should be |
| 82 | * declared [FLEXIBLE_ARRAY_MEMBER], but for some reason you can't do that |
| 83 | * in an otherwise-empty struct. |
| 84 | */ |
| 85 | ItemPointerData rm_tids[1]; |
| 86 | } RevmapContents; |
| 87 | |
| 88 | #define REVMAP_CONTENT_SIZE \ |
| 89 | (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \ |
| 90 | offsetof(RevmapContents, rm_tids) - \ |
| 91 | MAXALIGN(sizeof(BrinSpecialSpace))) |
| 92 | /* max num of items in the array */ |
| 93 | #define REVMAP_PAGE_MAXITEMS \ |
| 94 | (REVMAP_CONTENT_SIZE / sizeof(ItemPointerData)) |
| 95 | |
| 96 | #endif /* BRIN_PAGE_H */ |
| 97 | |