1 /*-------------------------------------------------------------------------
2  *
3  * hash_xlog.h
4  *	  header file for Postgres hash AM implementation
5  *
6  *
7  * Portions Copyright (c) 1996-2018, 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  */
59 typedef 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  */
75 typedef 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  */
93 typedef 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  */
111 typedef 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  */
130 typedef 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  */
149 typedef 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  */
172 typedef 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  */
197 typedef 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  */
214 typedef 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  */
229 typedef 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  */
247 typedef 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  */
264 typedef struct xl_hash_vacuum_one_page
265 {
266 	RelFileNode hnode;
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 
275 extern void hash_redo(XLogReaderState *record);
276 extern void hash_desc(StringInfo buf, XLogReaderState *record);
277 extern const char *hash_identify(uint8 info);
278 extern void hash_mask(char *pagedata, BlockNumber blkno);
279 
280 #endif							/* HASH_XLOG_H */
281