34
35
#include "page0types.h"
35
36
#include "buf0types.h"
36
37
#include "dict0types.h"
38
#include "trx0types.h"
37
39
#include "mem0mem.h"
39
/**************************************************************************
40
Determine the size of a compressed page in bytes. */
41
/**********************************************************************//**
42
Determine the size of a compressed page in bytes.
43
@return size in bytes */
45
/* out: size in bytes */
46
const page_zip_des_t* page_zip) /* in: compressed page */
48
const page_zip_des_t* page_zip) /*!< in: compressed page */
47
49
__attribute__((nonnull, pure));
48
/**************************************************************************
50
/**********************************************************************//**
49
51
Set the size of a compressed page in bytes. */
54
page_zip_des_t* page_zip, /* in/out: compressed page */
55
ulint size); /* in: size in bytes */
56
page_zip_des_t* page_zip, /*!< in/out: compressed page */
57
ulint size); /*!< in: size in bytes */
57
/**************************************************************************
58
Determine if a record is so big that it needs to be stored externally. */
59
#ifndef UNIV_HOTBACKUP
60
/**********************************************************************//**
61
Determine if a record is so big that it needs to be stored externally.
62
@return FALSE if the entire record can be stored locally on the page */
61
65
page_zip_rec_needs_ext(
62
66
/*===================*/
63
/* out: FALSE if the entire record
64
can be stored locally on the page */
65
ulint rec_size, /* in: length of the record in bytes */
66
ulint comp, /* in: nonzero=compact format */
67
ulint n_fields, /* in: number of fields in the record;
67
ulint rec_size, /*!< in: length of the record in bytes */
68
ulint comp, /*!< in: nonzero=compact format */
69
ulint n_fields, /*!< in: number of fields in the record;
68
70
ignored if zip_size == 0 */
69
ulint zip_size) /* in: compressed page size in bytes, or 0 */
70
__attribute__((__const__));
71
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
72
__attribute__((const));
72
/**************************************************************************
73
Determine the guaranteed free space on an empty page. */
74
/**********************************************************************//**
75
Determine the guaranteed free space on an empty page.
76
@return minimum payload size on the page */
76
79
page_zip_empty_size(
77
80
/*================*/
78
/* out: minimum payload size on the page */
79
ulint n_fields, /* in: number of columns in the index */
80
ulint zip_size) /* in: compressed page size in bytes */
81
ulint n_fields, /*!< in: number of columns in the index */
82
ulint zip_size) /*!< in: compressed page size in bytes */
81
83
__attribute__((const));
84
#endif /* !UNIV_HOTBACKUP */
83
/**************************************************************************
86
/**********************************************************************//**
84
87
Initialize a compressed page descriptor. */
89
page_zip_des_t* page_zip); /* in/out: compressed page
92
page_zip_des_t* page_zip); /*!< in/out: compressed page
92
/**************************************************************************
95
/**********************************************************************//**
93
96
Configure the zlib allocator to use the given memory heap. */
96
99
page_zip_set_alloc(
97
100
/*===============*/
98
void* stream, /* in/out: zlib stream */
99
mem_heap_t* heap); /* in: memory heap to use */
101
void* stream, /*!< in/out: zlib stream */
102
mem_heap_t* heap); /*!< in: memory heap to use */
101
/**************************************************************************
104
/**********************************************************************//**
106
@return TRUE on success, FALSE on failure; page_zip will be left
107
intact on failure. */
105
110
page_zip_compress(
106
111
/*==============*/
107
/* out: TRUE on success, FALSE on failure;
108
page_zip will be left intact on failure. */
109
page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
112
page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
110
113
m_start, m_end, m_nonempty */
111
const page_t* page, /* in: uncompressed page */
112
dict_index_t* index, /* in: index of the B-tree node */
113
mtr_t* mtr) /* in: mini-transaction, or NULL */
114
const page_t* page, /*!< in: uncompressed page */
115
dict_index_t* index, /*!< in: index of the B-tree node */
116
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
114
117
__attribute__((nonnull(1,2,3)));
116
/**************************************************************************
119
/**********************************************************************//**
117
120
Decompress a page. This function should tolerate errors on the compressed
118
121
page. Instead of letting assertions fail, it will return FALSE if an
119
inconsistency is detected. */
122
inconsistency is detected.
123
@return TRUE on success, FALSE on failure */
122
126
page_zip_decompress(
123
127
/*================*/
124
/* out: TRUE on success, FALSE on failure */
125
page_zip_des_t* page_zip,/* in: data, ssize;
128
page_zip_des_t* page_zip,/*!< in: data, ssize;
126
129
out: m_start, m_end, m_nonempty, n_blobs */
127
page_t* page) /* out: uncompressed page, may be trashed */
130
page_t* page) /*!< out: uncompressed page, may be trashed */
128
131
__attribute__((nonnull));
130
133
#ifdef UNIV_DEBUG
131
/**************************************************************************
132
Validate a compressed page descriptor. */
134
/**********************************************************************//**
135
Validate a compressed page descriptor.
136
@return TRUE if ok */
135
139
page_zip_simple_validate(
136
140
/*=====================*/
137
/* out: TRUE if ok */
138
const page_zip_des_t* page_zip); /* in: compressed page
141
const page_zip_des_t* page_zip); /*!< in: compressed page
140
143
#endif /* UNIV_DEBUG */
142
145
#ifdef UNIV_ZIP_DEBUG
143
/**************************************************************************
144
Check that the compressed and decompressed pages match. */
146
/**********************************************************************//**
147
Check that the compressed and decompressed pages match.
148
@return TRUE if valid, FALSE if not */
147
151
page_zip_validate_low(
148
152
/*==================*/
149
/* out: TRUE if valid, FALSE if not */
150
const page_zip_des_t* page_zip,/* in: compressed page */
151
const page_t* page, /* in: uncompressed page */
152
ibool sloppy) /* in: FALSE=strict,
153
const page_zip_des_t* page_zip,/*!< in: compressed page */
154
const page_t* page, /*!< in: uncompressed page */
155
ibool sloppy) /*!< in: FALSE=strict,
153
156
TRUE=ignore the MIN_REC_FLAG */
154
157
__attribute__((nonnull));
155
/**************************************************************************
158
/**********************************************************************//**
156
159
Check that the compressed and decompressed pages match. */
159
162
page_zip_validate(
160
163
/*==============*/
161
const page_zip_des_t* page_zip,/* in: compressed page */
162
const page_t* page) /* in: uncompressed page */
164
const page_zip_des_t* page_zip,/*!< in: compressed page */
165
const page_t* page) /*!< in: uncompressed page */
163
166
__attribute__((nonnull));
164
167
#endif /* UNIV_ZIP_DEBUG */
166
/**************************************************************************
167
Determine how big record can be inserted without recompressing the page. */
169
/**********************************************************************//**
170
Determine how big record can be inserted without recompressing the page.
171
@return a positive number indicating the maximum size of a record
172
whose insertion is guaranteed to succeed, or zero or negative */
170
175
page_zip_max_ins_size(
171
176
/*==================*/
172
/* out: a positive number
173
indicating the maximum size of
174
a record whose insertion is
175
guaranteed to succeed, or
177
const page_zip_des_t* page_zip,/* in: compressed page */
178
ibool is_clust)/* in: TRUE if clustered index */
177
const page_zip_des_t* page_zip,/*!< in: compressed page */
178
ibool is_clust)/*!< in: TRUE if clustered index */
179
179
__attribute__((nonnull, pure));
181
/**************************************************************************
182
Determine if enough space is available in the modification log. */
181
/**********************************************************************//**
182
Determine if enough space is available in the modification log.
183
@return TRUE if page_zip_write_rec() will succeed */
185
186
page_zip_available(
186
187
/*===============*/
187
/* out: TRUE if page_zip_write_rec()
189
const page_zip_des_t* page_zip,/* in: compressed page */
190
ibool is_clust,/* in: TRUE if clustered index */
191
ulint length, /* in: combined size of the record */
192
ulint create) /* in: nonzero=add the record to
188
const page_zip_des_t* page_zip,/*!< in: compressed page */
189
ibool is_clust,/*!< in: TRUE if clustered index */
190
ulint length, /*!< in: combined size of the record */
191
ulint create) /*!< in: nonzero=add the record to
194
193
__attribute__((nonnull, pure));
196
/**************************************************************************
195
/**********************************************************************//**
196
Write data to the uncompressed header portion of a page. The data must
197
already have been written to the uncompressed page. */
200
page_zip_write_header(
201
/*==================*/
202
page_zip_des_t* page_zip,/*!< in/out: compressed page */
203
const byte* str, /*!< in: address on the uncompressed page */
204
ulint length, /*!< in: length of the data */
205
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
206
__attribute__((nonnull(1,2)));
208
/**********************************************************************//**
197
209
Write an entire record on the compressed page. The data must already
198
210
have been written to the uncompressed page. */
201
213
page_zip_write_rec(
202
214
/*===============*/
203
page_zip_des_t* page_zip,/* in/out: compressed page */
204
const byte* rec, /* in: record being written */
205
dict_index_t* index, /* in: the index the record belongs to */
206
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
207
ulint create) /* in: nonzero=insert, zero=update */
215
page_zip_des_t* page_zip,/*!< in/out: compressed page */
216
const byte* rec, /*!< in: record being written */
217
dict_index_t* index, /*!< in: the index the record belongs to */
218
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
219
ulint create) /*!< in: nonzero=insert, zero=update */
208
220
__attribute__((nonnull));
210
/***************************************************************
211
Parses a log record of writing a BLOB pointer of a record. */
222
/***********************************************************//**
223
Parses a log record of writing a BLOB pointer of a record.
224
@return end of log record or NULL */
214
227
page_zip_parse_write_blob_ptr(
215
228
/*==========================*/
216
/* out: end of log record or NULL */
217
byte* ptr, /* in: redo log buffer */
218
byte* end_ptr,/* in: redo log buffer end */
219
page_t* page, /* in/out: uncompressed page */
220
page_zip_des_t* page_zip);/* in/out: compressed page */
229
byte* ptr, /*!< in: redo log buffer */
230
byte* end_ptr,/*!< in: redo log buffer end */
231
page_t* page, /*!< in/out: uncompressed page */
232
page_zip_des_t* page_zip);/*!< in/out: compressed page */
222
/**************************************************************************
234
/**********************************************************************//**
223
235
Write a BLOB pointer of a record on the leaf page of a clustered index.
224
236
The information must already have been updated on the uncompressed page. */
227
239
page_zip_write_blob_ptr(
228
240
/*====================*/
229
page_zip_des_t* page_zip,/* in/out: compressed page */
230
const byte* rec, /* in/out: record whose data is being
241
page_zip_des_t* page_zip,/*!< in/out: compressed page */
242
const byte* rec, /*!< in/out: record whose data is being
232
dict_index_t* index, /* in: index of the page */
233
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
234
ulint n, /* in: column index */
235
mtr_t* mtr) /* in: mini-transaction handle,
244
dict_index_t* index, /*!< in: index of the page */
245
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
246
ulint n, /*!< in: column index */
247
mtr_t* mtr) /*!< in: mini-transaction handle,
236
248
or NULL if no logging is needed */
237
249
__attribute__((nonnull(1,2,3,4)));
239
/***************************************************************
240
Parses a log record of writing the node pointer of a record. */
251
/***********************************************************//**
252
Parses a log record of writing the node pointer of a record.
253
@return end of log record or NULL */
243
256
page_zip_parse_write_node_ptr(
244
257
/*==========================*/
245
/* out: end of log record or NULL */
246
byte* ptr, /* in: redo log buffer */
247
byte* end_ptr,/* in: redo log buffer end */
248
page_t* page, /* in/out: uncompressed page */
249
page_zip_des_t* page_zip);/* in/out: compressed page */
258
byte* ptr, /*!< in: redo log buffer */
259
byte* end_ptr,/*!< in: redo log buffer end */
260
page_t* page, /*!< in/out: uncompressed page */
261
page_zip_des_t* page_zip);/*!< in/out: compressed page */
251
/**************************************************************************
263
/**********************************************************************//**
252
264
Write the node pointer of a record on a non-leaf compressed page. */
255
267
page_zip_write_node_ptr(
256
268
/*====================*/
257
page_zip_des_t* page_zip,/* in/out: compressed page */
258
byte* rec, /* in/out: record */
259
ulint size, /* in: data size of rec */
260
ulint ptr, /* in: node pointer */
261
mtr_t* mtr) /* in: mini-transaction, or NULL */
269
page_zip_des_t* page_zip,/*!< in/out: compressed page */
270
byte* rec, /*!< in/out: record */
271
ulint size, /*!< in: data size of rec */
272
ulint ptr, /*!< in: node pointer */
273
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
262
274
__attribute__((nonnull(1,2)));
264
/**************************************************************************
276
/**********************************************************************//**
265
277
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
268
280
page_zip_write_trx_id_and_roll_ptr(
269
281
/*===============================*/
270
page_zip_des_t* page_zip,/* in/out: compressed page */
271
byte* rec, /* in/out: record */
272
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
273
ulint trx_id_col,/* in: column number of TRX_ID in rec */
274
dulint trx_id, /* in: transaction identifier */
275
dulint roll_ptr)/* in: roll_ptr */
282
page_zip_des_t* page_zip,/*!< in/out: compressed page */
283
byte* rec, /*!< in/out: record */
284
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
285
ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
286
trx_id_t trx_id, /*!< in: transaction identifier */
287
roll_ptr_t roll_ptr)/*!< in: roll_ptr */
276
288
__attribute__((nonnull));
278
/**************************************************************************
291
/**********************************************************************//**
279
292
Insert a record to the dense page directory. */
282
295
page_zip_dir_insert(
283
296
/*================*/
284
page_zip_des_t* page_zip,/* in/out: compressed page */
285
const byte* prev_rec,/* in: record after which to insert */
286
const byte* free_rec,/* in: record from which rec was
297
page_zip_des_t* page_zip,/*!< in/out: compressed page */
298
const byte* prev_rec,/*!< in: record after which to insert */
299
const byte* free_rec,/*!< in: record from which rec was
287
300
allocated, or NULL */
288
byte* rec); /* in: record to insert */
301
byte* rec); /*!< in: record to insert */
290
/***************************************************************
291
Parses a log record of writing to the header of a page. */
294
305
page_zip_parse_write_header(
295
306
/*========================*/
296
/* out: end of log record or NULL */
297
byte* ptr, /* in: redo log buffer */
298
byte* end_ptr,/* in: redo log buffer end */
299
page_t* page, /* in/out: uncompressed page */
300
page_zip_des_t* page_zip);/* in/out: compressed page */
302
/**************************************************************************
303
Write data to the uncompressed header portion of a page. The data must
304
already have been written to the uncompressed page.
305
However, the data portion of the uncompressed page may differ from
306
the compressed page when a record is being inserted in
307
page_cur_insert_rec_low(). */
310
page_zip_write_header(
311
/*==================*/
312
page_zip_des_t* page_zip,/* in/out: compressed page */
313
const byte* str, /* in: address on the uncompressed page */
314
ulint length, /* in: length of the data */
315
mtr_t* mtr) /* in: mini-transaction, or NULL */
316
__attribute__((nonnull(1,2)));
318
/**************************************************************************
307
byte* ptr, /*!< in: redo log buffer */
308
byte* end_ptr,/*!< in: redo log buffer end */
309
page_t* page, /*!< in/out: uncompressed page */
310
page_zip_des_t* page_zip);/*!< in/out: compressed page */
313
/**********************************************************************//**
319
314
Reorganize and compress a page. This is a low-level operation for
320
315
compressed pages, to be used when page_zip_compress() fails.
321
316
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.