1
/*****************************************************************************
3
Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/page0zip.h
21
Compressed page interface
23
Created June 2005 by Marko Makela
24
*******************************************************/
29
#ifdef UNIV_MATERIALIZE
34
#include "mtr0types.h"
35
#include "page0types.h"
36
#include "buf0types.h"
37
#include "dict0types.h"
38
#include "trx0types.h"
41
/**********************************************************************//**
42
Determine the size of a compressed page in bytes.
43
@return size in bytes */
48
const page_zip_des_t* page_zip) /*!< in: compressed page */
49
__attribute__((nonnull, pure));
50
/**********************************************************************//**
51
Set the size of a compressed page in bytes. */
56
page_zip_des_t* page_zip, /*!< in/out: compressed page */
57
ulint size); /*!< in: size in bytes */
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 */
65
page_zip_rec_needs_ext(
66
/*===================*/
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;
70
ignored if zip_size == 0 */
71
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
72
__attribute__((const));
74
/**********************************************************************//**
75
Determine the guaranteed free space on an empty page.
76
@return minimum payload size on the page */
81
ulint n_fields, /*!< in: number of columns in the index */
82
ulint zip_size) /*!< in: compressed page size in bytes */
83
__attribute__((const));
84
#endif /* !UNIV_HOTBACKUP */
86
/**********************************************************************//**
87
Initialize a compressed page descriptor. */
92
page_zip_des_t* page_zip); /*!< in/out: compressed page
95
/**********************************************************************//**
96
Configure the zlib allocator to use the given memory heap. */
101
void* stream, /*!< in/out: zlib stream */
102
mem_heap_t* heap); /*!< in: memory heap to use */
104
/**********************************************************************//**
106
@return TRUE on success, FALSE on failure; page_zip will be left
107
intact on failure. */
112
page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
113
m_start, m_end, m_nonempty */
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 */
117
__attribute__((nonnull(1,2,3)));
119
/**********************************************************************//**
120
Decompress a page. This function should tolerate errors on the compressed
121
page. Instead of letting assertions fail, it will return FALSE if an
122
inconsistency is detected.
123
@return TRUE on success, FALSE on failure */
128
page_zip_des_t* page_zip,/*!< in: data, ssize;
129
out: m_start, m_end, m_nonempty, n_blobs */
130
page_t* page) /*!< out: uncompressed page, may be trashed */
131
__attribute__((nonnull));
134
/**********************************************************************//**
135
Validate a compressed page descriptor.
136
@return TRUE if ok */
139
page_zip_simple_validate(
140
/*=====================*/
141
const page_zip_des_t* page_zip); /*!< in: compressed page
143
#endif /* UNIV_DEBUG */
145
#ifdef UNIV_ZIP_DEBUG
146
/**********************************************************************//**
147
Check that the compressed and decompressed pages match.
148
@return TRUE if valid, FALSE if not */
151
page_zip_validate_low(
152
/*==================*/
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,
156
TRUE=ignore the MIN_REC_FLAG */
157
__attribute__((nonnull));
158
/**********************************************************************//**
159
Check that the compressed and decompressed pages match. */
164
const page_zip_des_t* page_zip,/*!< in: compressed page */
165
const page_t* page) /*!< in: uncompressed page */
166
__attribute__((nonnull));
167
#endif /* UNIV_ZIP_DEBUG */
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 */
175
page_zip_max_ins_size(
176
/*==================*/
177
const page_zip_des_t* page_zip,/*!< in: compressed page */
178
ibool is_clust)/*!< in: TRUE if clustered index */
179
__attribute__((nonnull, pure));
181
/**********************************************************************//**
182
Determine if enough space is available in the modification log.
183
@return TRUE if page_zip_write_rec() will succeed */
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
193
__attribute__((nonnull, pure));
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
/**********************************************************************//**
209
Write an entire record on the compressed page. The data must already
210
have been written to the uncompressed page. */
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 */
220
__attribute__((nonnull));
222
/***********************************************************//**
223
Parses a log record of writing a BLOB pointer of a record.
224
@return end of log record or NULL */
227
page_zip_parse_write_blob_ptr(
228
/*==========================*/
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 */
234
/**********************************************************************//**
235
Write a BLOB pointer of a record on the leaf page of a clustered index.
236
The information must already have been updated on the uncompressed page. */
239
page_zip_write_blob_ptr(
240
/*====================*/
241
page_zip_des_t* page_zip,/*!< in/out: compressed page */
242
const byte* rec, /*!< in/out: record whose data is being
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,
248
or NULL if no logging is needed */
249
__attribute__((nonnull(1,2,3,4)));
251
/***********************************************************//**
252
Parses a log record of writing the node pointer of a record.
253
@return end of log record or NULL */
256
page_zip_parse_write_node_ptr(
257
/*==========================*/
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 */
263
/**********************************************************************//**
264
Write the node pointer of a record on a non-leaf compressed page. */
267
page_zip_write_node_ptr(
268
/*====================*/
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 */
274
__attribute__((nonnull(1,2)));
276
/**********************************************************************//**
277
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
280
page_zip_write_trx_id_and_roll_ptr(
281
/*===============================*/
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 */
288
__attribute__((nonnull));
291
/**********************************************************************//**
292
Insert a record to the dense page directory. */
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
300
allocated, or NULL */
301
byte* rec); /*!< in: record to insert */
305
page_zip_parse_write_header(
306
/*========================*/
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
/**********************************************************************//**
314
Reorganize and compress a page. This is a low-level operation for
315
compressed pages, to be used when page_zip_compress() fails.
316
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
317
The function btr_page_reorganize() should be preferred whenever possible.
318
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
319
non-clustered index, the caller must update the insert buffer free
320
bits in the same mini-transaction in such a way that the modification
322
@return TRUE on success, FALSE on failure; page and page_zip will be
323
left intact on failure. */
328
buf_block_t* block, /*!< in/out: page with compressed page;
329
on the compressed page, in: size;
331
m_start, m_end, m_nonempty */
332
dict_index_t* index, /*!< in: index of the B-tree node */
333
mtr_t* mtr) /*!< in: mini-transaction */
334
__attribute__((nonnull));
335
#ifndef UNIV_HOTBACKUP
336
/**********************************************************************//**
337
Copy the records of a page byte for byte. Do not copy the page header
338
or trailer, except those B-tree header fields that are directly
339
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
340
NOTE: The caller must update the lock table and the adaptive hash index. */
345
page_zip_des_t* page_zip, /*!< out: copy of src_zip
346
(n_blobs, m_start, m_end,
347
m_nonempty, data[0..size-1]) */
348
page_t* page, /*!< out: copy of src */
349
const page_zip_des_t* src_zip, /*!< in: compressed page */
350
const page_t* src, /*!< in: page */
351
dict_index_t* index, /*!< in: index of the B-tree */
352
mtr_t* mtr) /*!< in: mini-transaction */
353
__attribute__((nonnull(1,2,3,4)));
354
#endif /* !UNIV_HOTBACKUP */
356
/**********************************************************************//**
357
Parses a log record of compressing an index page.
358
@return end of log record or NULL */
361
page_zip_parse_compress(
362
/*====================*/
363
byte* ptr, /*!< in: buffer */
364
byte* end_ptr,/*!< in: buffer end */
365
page_t* page, /*!< out: uncompressed page */
366
page_zip_des_t* page_zip)/*!< out: compressed page */
367
__attribute__((nonnull(1,2)));
369
/**********************************************************************//**
370
Calculate the compressed page checksum.
371
@return page checksum */
374
page_zip_calc_checksum(
375
/*===================*/
376
const void* data, /*!< in: compressed page */
377
ulint size) /*!< in: size of compressed page */
378
__attribute__((nonnull));
380
#ifndef UNIV_HOTBACKUP
381
/** Check if a pointer to an uncompressed page matches a compressed page.
382
@param ptr pointer to an uncompressed page frame
383
@param page_zip compressed page descriptor
384
@return TRUE if ptr and page_zip refer to the same block */
385
# define PAGE_ZIP_MATCH(ptr, page_zip) \
386
(buf_frame_get_page_zip(ptr) == (page_zip))
387
#else /* !UNIV_HOTBACKUP */
388
/** Check if a pointer to an uncompressed page matches a compressed page.
389
@param ptr pointer to an uncompressed page frame
390
@param page_zip compressed page descriptor
391
@return TRUE if ptr and page_zip refer to the same block */
392
# define PAGE_ZIP_MATCH(ptr, page_zip) \
393
(page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
394
#endif /* !UNIV_HOTBACKUP */
396
#ifdef UNIV_MATERIALIZE
398
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
402
# include "page0zip.ic"
405
#endif /* page0zip_h */