1/*-------------------------------------------------------------------------
2 *
3 * hash_xlog.h
4 * header file for Postgres hash AM implementation
5 *
6 *
7 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/include/access/hash_xlog.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef HASH_XLOG_H
15#define HASH_XLOG_H
16
17#include "access/xlogreader.h"
18#include "lib/stringinfo.h"
19#include "storage/off.h"
20
21/* Number of buffers required for XLOG_HASH_SQUEEZE_PAGE operation */
22#define HASH_XLOG_FREE_OVFL_BUFS 6
23
24/*
25 * XLOG records for hash operations
26 */
27#define XLOG_HASH_INIT_META_PAGE 0x00 /* initialize the meta page */
28#define XLOG_HASH_INIT_BITMAP_PAGE 0x10 /* initialize the bitmap page */
29#define XLOG_HASH_INSERT 0x20 /* add index tuple without split */
30#define XLOG_HASH_ADD_OVFL_PAGE 0x30 /* add overflow page */
31#define XLOG_HASH_SPLIT_ALLOCATE_PAGE 0x40 /* allocate new page for split */
32#define XLOG_HASH_SPLIT_PAGE 0x50 /* split page */
33#define XLOG_HASH_SPLIT_COMPLETE 0x60 /* completion of split operation */
34#define XLOG_HASH_MOVE_PAGE_CONTENTS 0x70 /* remove tuples from one page
35 * and add to another page */
36#define XLOG_HASH_SQUEEZE_PAGE 0x80 /* add tuples to one of the previous
37 * pages in chain and free the ovfl
38 * page */
39#define XLOG_HASH_DELETE 0x90 /* delete index tuples from a page */
40#define XLOG_HASH_SPLIT_CLEANUP 0xA0 /* clear split-cleanup flag in primary
41 * bucket page after deleting tuples
42 * that are moved due to split */
43#define XLOG_HASH_UPDATE_META_PAGE 0xB0 /* update meta page after vacuum */
44
45#define XLOG_HASH_VACUUM_ONE_PAGE 0xC0 /* remove dead tuples from index
46 * page */
47
48/*
49 * xl_hash_split_allocate_page flag values, 8 bits are available.
50 */
51#define XLH_SPLIT_META_UPDATE_MASKS (1<<0)
52#define XLH_SPLIT_META_UPDATE_SPLITPOINT (1<<1)
53
54/*
55 * This is what we need to know about a HASH index create.
56 *
57 * Backup block 0: metapage
58 */
59typedef struct xl_hash_createidx
60{
61 double num_tuples;
62 RegProcedure procid;
63 uint16 ffactor;
64} xl_hash_createidx;
65#define SizeOfHashCreateIdx (offsetof(xl_hash_createidx, ffactor) + sizeof(uint16))
66
67/*
68 * This is what we need to know about simple (without split) insert.
69 *
70 * This data record is used for XLOG_HASH_INSERT
71 *
72 * Backup Blk 0: original page (data contains the inserted tuple)
73 * Backup Blk 1: metapage (HashMetaPageData)
74 */
75typedef struct xl_hash_insert
76{
77 OffsetNumber offnum;
78} xl_hash_insert;
79
80#define SizeOfHashInsert (offsetof(xl_hash_insert, offnum) + sizeof(OffsetNumber))
81
82/*
83 * This is what we need to know about addition of overflow page.
84 *
85 * This data record is used for XLOG_HASH_ADD_OVFL_PAGE
86 *
87 * Backup Blk 0: newly allocated overflow page
88 * Backup Blk 1: page before new overflow page in the bucket chain
89 * Backup Blk 2: bitmap page
90 * Backup Blk 3: new bitmap page
91 * Backup Blk 4: metapage
92 */
93typedef struct xl_hash_add_ovfl_page
94{
95 uint16 bmsize;
96 bool bmpage_found;
97} xl_hash_add_ovfl_page;
98
99#define SizeOfHashAddOvflPage \
100 (offsetof(xl_hash_add_ovfl_page, bmpage_found) + sizeof(bool))
101
102/*
103 * This is what we need to know about allocating a page for split.
104 *
105 * This data record is used for XLOG_HASH_SPLIT_ALLOCATE_PAGE
106 *
107 * Backup Blk 0: page for old bucket
108 * Backup Blk 1: page for new bucket
109 * Backup Blk 2: metapage
110 */
111typedef struct xl_hash_split_allocate_page
112{
113 uint32 new_bucket;
114 uint16 old_bucket_flag;
115 uint16 new_bucket_flag;
116 uint8 flags;
117} xl_hash_split_allocate_page;
118
119#define SizeOfHashSplitAllocPage \
120 (offsetof(xl_hash_split_allocate_page, flags) + sizeof(uint8))
121
122/*
123 * This is what we need to know about completing the split operation.
124 *
125 * This data record is used for XLOG_HASH_SPLIT_COMPLETE
126 *
127 * Backup Blk 0: page for old bucket
128 * Backup Blk 1: page for new bucket
129 */
130typedef struct xl_hash_split_complete
131{
132 uint16 old_bucket_flag;
133 uint16 new_bucket_flag;
134} xl_hash_split_complete;
135
136#define SizeOfHashSplitComplete \
137 (offsetof(xl_hash_split_complete, new_bucket_flag) + sizeof(uint16))
138
139/*
140 * This is what we need to know about move page contents required during
141 * squeeze operation.
142 *
143 * This data record is used for XLOG_HASH_MOVE_PAGE_CONTENTS
144 *
145 * Backup Blk 0: bucket page
146 * Backup Blk 1: page containing moved tuples
147 * Backup Blk 2: page from which tuples will be removed
148 */
149typedef struct xl_hash_move_page_contents
150{
151 uint16 ntups;
152 bool is_prim_bucket_same_wrt; /* true if the page to which
153 * tuples are moved is same as
154 * primary bucket page */
155} xl_hash_move_page_contents;
156
157#define SizeOfHashMovePageContents \
158 (offsetof(xl_hash_move_page_contents, is_prim_bucket_same_wrt) + sizeof(bool))
159
160/*
161 * This is what we need to know about the squeeze page operation.
162 *
163 * This data record is used for XLOG_HASH_SQUEEZE_PAGE
164 *
165 * Backup Blk 0: page containing tuples moved from freed overflow page
166 * Backup Blk 1: freed overflow page
167 * Backup Blk 2: page previous to the freed overflow page
168 * Backup Blk 3: page next to the freed overflow page
169 * Backup Blk 4: bitmap page containing info of freed overflow page
170 * Backup Blk 5: meta page
171 */
172typedef struct xl_hash_squeeze_page
173{
174 BlockNumber prevblkno;
175 BlockNumber nextblkno;
176 uint16 ntups;
177 bool is_prim_bucket_same_wrt; /* true if the page to which
178 * tuples are moved is same as
179 * primary bucket page */
180 bool is_prev_bucket_same_wrt; /* true if the page to which
181 * tuples are moved is the page
182 * previous to the freed overflow
183 * page */
184} xl_hash_squeeze_page;
185
186#define SizeOfHashSqueezePage \
187 (offsetof(xl_hash_squeeze_page, is_prev_bucket_same_wrt) + sizeof(bool))
188
189/*
190 * This is what we need to know about the deletion of index tuples from a page.
191 *
192 * This data record is used for XLOG_HASH_DELETE
193 *
194 * Backup Blk 0: primary bucket page
195 * Backup Blk 1: page from which tuples are deleted
196 */
197typedef struct xl_hash_delete
198{
199 bool clear_dead_marking; /* true if this operation clears
200 * LH_PAGE_HAS_DEAD_TUPLES flag */
201 bool is_primary_bucket_page; /* true if the operation is for
202 * primary bucket page */
203} xl_hash_delete;
204
205#define SizeOfHashDelete (offsetof(xl_hash_delete, is_primary_bucket_page) + sizeof(bool))
206
207/*
208 * This is what we need for metapage update operation.
209 *
210 * This data record is used for XLOG_HASH_UPDATE_META_PAGE
211 *
212 * Backup Blk 0: meta page
213 */
214typedef struct xl_hash_update_meta_page
215{
216 double ntuples;
217} xl_hash_update_meta_page;
218
219#define SizeOfHashUpdateMetaPage \
220 (offsetof(xl_hash_update_meta_page, ntuples) + sizeof(double))
221
222/*
223 * This is what we need to initialize metapage.
224 *
225 * This data record is used for XLOG_HASH_INIT_META_PAGE
226 *
227 * Backup Blk 0: meta page
228 */
229typedef struct xl_hash_init_meta_page
230{
231 double num_tuples;
232 RegProcedure procid;
233 uint16 ffactor;
234} xl_hash_init_meta_page;
235
236#define SizeOfHashInitMetaPage \
237 (offsetof(xl_hash_init_meta_page, ffactor) + sizeof(uint16))
238
239/*
240 * This is what we need to initialize bitmap page.
241 *
242 * This data record is used for XLOG_HASH_INIT_BITMAP_PAGE
243 *
244 * Backup Blk 0: bitmap page
245 * Backup Blk 1: meta page
246 */
247typedef struct xl_hash_init_bitmap_page
248{
249 uint16 bmsize;
250} xl_hash_init_bitmap_page;
251
252#define SizeOfHashInitBitmapPage \
253 (offsetof(xl_hash_init_bitmap_page, bmsize) + sizeof(uint16))
254
255/*
256 * This is what we need for index tuple deletion and to
257 * update the meta page.
258 *
259 * This data record is used for XLOG_HASH_VACUUM_ONE_PAGE
260 *
261 * Backup Blk 0: bucket page
262 * Backup Blk 1: meta page
263 */
264typedef struct xl_hash_vacuum_one_page
265{
266 TransactionId latestRemovedXid;
267 int ntuples;
268
269 /* TARGET OFFSET NUMBERS FOLLOW AT THE END */
270} xl_hash_vacuum_one_page;
271
272#define SizeOfHashVacuumOnePage \
273 (offsetof(xl_hash_vacuum_one_page, ntuples) + sizeof(int))
274
275extern void hash_redo(XLogReaderState *record);
276extern void hash_desc(StringInfo buf, XLogReaderState *record);
277extern const char *hash_identify(uint8 info);
278extern void hash_mask(char *pagedata, BlockNumber blkno);
279
280#endif /* HASH_XLOG_H */
281