~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/page0page.h

  • Committer: Daniel Nichter
  • Date: 2011-10-23 16:01:37 UTC
  • mto: This revision was merged to the branch mainline in revision 2448.
  • Revision ID: daniel@percona.com-20111023160137-7ac3blgz8z4tf8za
Add Administration Getting Started and Logging.  Capitalize SQL clause keywords.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (C) 1994, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
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.
 
8
 
 
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.
 
12
 
 
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., 51 Franklin
 
15
St, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file include/page0page.h
 
21
Index page routines
 
22
 
 
23
Created 2/2/1994 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#pragma once
 
27
#ifndef page0page_h
 
28
#define page0page_h
 
29
 
 
30
#include "univ.i"
 
31
 
 
32
#include "page0types.h"
 
33
#include "fil0fil.h"
 
34
#include "buf0buf.h"
 
35
#include "data0data.h"
 
36
#include "dict0dict.h"
 
37
#include "rem0rec.h"
 
38
#include "fsp0fsp.h"
 
39
#include "mtr0mtr.h"
 
40
 
 
41
#ifdef UNIV_MATERIALIZE
 
42
#undef UNIV_INLINE
 
43
#define UNIV_INLINE
 
44
#endif
 
45
 
 
46
/*                      PAGE HEADER
 
47
                        ===========
 
48
 
 
49
Index page header starts at the first offset left free by the FIL-module */
 
50
 
 
51
typedef byte            page_header_t;
 
52
 
 
53
#define PAGE_HEADER     FSEG_PAGE_DATA  /* index page header starts at this
 
54
                                offset */
 
55
/*-----------------------------*/
 
56
#define PAGE_N_DIR_SLOTS 0      /* number of slots in page directory */
 
57
#define PAGE_HEAP_TOP    2      /* pointer to record heap top */
 
58
#define PAGE_N_HEAP      4      /* number of records in the heap,
 
59
                                bit 15=flag: new-style compact page format */
 
60
#define PAGE_FREE        6      /* pointer to start of page free record list */
 
61
#define PAGE_GARBAGE     8      /* number of bytes in deleted records */
 
62
#define PAGE_LAST_INSERT 10     /* pointer to the last inserted record, or
 
63
                                NULL if this info has been reset by a delete,
 
64
                                for example */
 
65
#define PAGE_DIRECTION   12     /* last insert direction: PAGE_LEFT, ... */
 
66
#define PAGE_N_DIRECTION 14     /* number of consecutive inserts to the same
 
67
                                direction */
 
68
#define PAGE_N_RECS      16     /* number of user records on the page */
 
69
#define PAGE_MAX_TRX_ID  18     /* highest id of a trx which may have modified
 
70
                                a record on the page; trx_id_t; defined only
 
71
                                in secondary indexes and in the insert buffer
 
72
                                tree; NOTE: this may be modified only
 
73
                                when the thread has an x-latch to the page,
 
74
                                and ALSO an x-latch to btr_search_latch
 
75
                                if there is a hash index to the page! */
 
76
#define PAGE_HEADER_PRIV_END 26 /* end of private data structure of the page
 
77
                                header which are set in a page create */
 
78
/*----*/
 
79
#define PAGE_LEVEL       26     /* level of the node in an index tree; the
 
80
                                leaf level is the level 0.  This field should
 
81
                                not be written to after page creation. */
 
82
#define PAGE_INDEX_ID    28     /* index id where the page belongs.
 
83
                                This field should not be written to after
 
84
                                page creation. */
 
85
#define PAGE_BTR_SEG_LEAF 36    /* file segment header for the leaf pages in
 
86
                                a B-tree: defined only on the root page of a
 
87
                                B-tree, but not in the root of an ibuf tree */
 
88
#define PAGE_BTR_IBUF_FREE_LIST PAGE_BTR_SEG_LEAF
 
89
#define PAGE_BTR_IBUF_FREE_LIST_NODE PAGE_BTR_SEG_LEAF
 
90
                                /* in the place of PAGE_BTR_SEG_LEAF and _TOP
 
91
                                there is a free list base node if the page is
 
92
                                the root page of an ibuf tree, and at the same
 
93
                                place is the free list node if the page is in
 
94
                                a free list */
 
95
#define PAGE_BTR_SEG_TOP (36 + FSEG_HEADER_SIZE)
 
96
                                /* file segment header for the non-leaf pages
 
97
                                in a B-tree: defined only on the root page of
 
98
                                a B-tree, but not in the root of an ibuf
 
99
                                tree */
 
100
/*----*/
 
101
#define PAGE_DATA       (PAGE_HEADER + 36 + 2 * FSEG_HEADER_SIZE)
 
102
                                /* start of data on the page */
 
103
 
 
104
#define PAGE_OLD_INFIMUM        (PAGE_DATA + 1 + REC_N_OLD_EXTRA_BYTES)
 
105
                                /* offset of the page infimum record on an
 
106
                                old-style page */
 
107
#define PAGE_OLD_SUPREMUM       (PAGE_DATA + 2 + 2 * REC_N_OLD_EXTRA_BYTES + 8)
 
108
                                /* offset of the page supremum record on an
 
109
                                old-style page */
 
110
#define PAGE_OLD_SUPREMUM_END (PAGE_OLD_SUPREMUM + 9)
 
111
                                /* offset of the page supremum record end on
 
112
                                an old-style page */
 
113
#define PAGE_NEW_INFIMUM        (PAGE_DATA + REC_N_NEW_EXTRA_BYTES)
 
114
                                /* offset of the page infimum record on a
 
115
                                new-style compact page */
 
116
#define PAGE_NEW_SUPREMUM       (PAGE_DATA + 2 * REC_N_NEW_EXTRA_BYTES + 8)
 
117
                                /* offset of the page supremum record on a
 
118
                                new-style compact page */
 
119
#define PAGE_NEW_SUPREMUM_END (PAGE_NEW_SUPREMUM + 8)
 
120
                                /* offset of the page supremum record end on
 
121
                                a new-style compact page */
 
122
/*-----------------------------*/
 
123
 
 
124
/* Heap numbers */
 
125
#define PAGE_HEAP_NO_INFIMUM    0       /* page infimum */
 
126
#define PAGE_HEAP_NO_SUPREMUM   1       /* page supremum */
 
127
#define PAGE_HEAP_NO_USER_LOW   2       /* first user record in
 
128
                                        creation (insertion) order,
 
129
                                        not necessarily collation order;
 
130
                                        this record may have been deleted */
 
131
 
 
132
/* Directions of cursor movement */
 
133
#define PAGE_LEFT               1
 
134
#define PAGE_RIGHT              2
 
135
#define PAGE_SAME_REC           3
 
136
#define PAGE_SAME_PAGE          4
 
137
#define PAGE_NO_DIRECTION       5
 
138
 
 
139
/*                      PAGE DIRECTORY
 
140
                        ==============
 
141
*/
 
142
 
 
143
typedef byte                    page_dir_slot_t;
 
144
typedef page_dir_slot_t         page_dir_t;
 
145
 
 
146
/* Offset of the directory start down from the page end. We call the
 
147
slot with the highest file address directory start, as it points to
 
148
the first record in the list of records. */
 
149
#define PAGE_DIR                FIL_PAGE_DATA_END
 
150
 
 
151
/* We define a slot in the page directory as two bytes */
 
152
#define PAGE_DIR_SLOT_SIZE      2
 
153
 
 
154
/* The offset of the physically lower end of the directory, counted from
 
155
page end, when the page is empty */
 
156
#define PAGE_EMPTY_DIR_START    (PAGE_DIR + 2 * PAGE_DIR_SLOT_SIZE)
 
157
 
 
158
/* The maximum and minimum number of records owned by a directory slot. The
 
159
number may drop below the minimum in the first and the last slot in the
 
160
directory. */
 
161
#define PAGE_DIR_SLOT_MAX_N_OWNED       8
 
162
#define PAGE_DIR_SLOT_MIN_N_OWNED       4
 
163
 
 
164
/************************************************************//**
 
165
Gets the start of a page.
 
166
@return start of the page */
 
167
UNIV_INLINE
 
168
page_t*
 
169
page_align(
 
170
/*=======*/
 
171
        const void*     ptr)    /*!< in: pointer to page frame */
 
172
                __attribute__((const));
 
173
/************************************************************//**
 
174
Gets the offset within a page.
 
175
@return offset from the start of the page */
 
176
UNIV_INLINE
 
177
ulint
 
178
page_offset(
 
179
/*========*/
 
180
        const void*     ptr)    /*!< in: pointer to page frame */
 
181
                __attribute__((const));
 
182
/*************************************************************//**
 
183
Returns the max trx id field value. */
 
184
UNIV_INLINE
 
185
trx_id_t
 
186
page_get_max_trx_id(
 
187
/*================*/
 
188
        const page_t*   page);  /*!< in: page */
 
189
/*************************************************************//**
 
190
Sets the max trx id field value. */
 
191
UNIV_INTERN
 
192
void
 
193
page_set_max_trx_id(
 
194
/*================*/
 
195
        buf_block_t*    block,  /*!< in/out: page */
 
196
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
197
        trx_id_t        trx_id, /*!< in: transaction id */
 
198
        mtr_t*          mtr);   /*!< in/out: mini-transaction, or NULL */
 
199
/*************************************************************//**
 
200
Sets the max trx id field value if trx_id is bigger than the previous
 
201
value. */
 
202
UNIV_INLINE
 
203
void
 
204
page_update_max_trx_id(
 
205
/*===================*/
 
206
        buf_block_t*    block,  /*!< in/out: page */
 
207
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
208
                                uncompressed part will be updated, or NULL */
 
209
        trx_id_t        trx_id, /*!< in: transaction id */
 
210
        mtr_t*          mtr);   /*!< in/out: mini-transaction */
 
211
/*************************************************************//**
 
212
Reads the given header field. */
 
213
UNIV_INLINE
 
214
ulint
 
215
page_header_get_field(
 
216
/*==================*/
 
217
        const page_t*   page,   /*!< in: page */
 
218
        ulint           field); /*!< in: PAGE_N_DIR_SLOTS, ... */
 
219
/*************************************************************//**
 
220
Sets the given header field. */
 
221
UNIV_INLINE
 
222
void
 
223
page_header_set_field(
 
224
/*==================*/
 
225
        page_t*         page,   /*!< in/out: page */
 
226
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
227
                                uncompressed part will be updated, or NULL */
 
228
        ulint           field,  /*!< in: PAGE_N_DIR_SLOTS, ... */
 
229
        ulint           val);   /*!< in: value */
 
230
/*************************************************************//**
 
231
Returns the offset stored in the given header field.
 
232
@return offset from the start of the page, or 0 */
 
233
UNIV_INLINE
 
234
ulint
 
235
page_header_get_offs(
 
236
/*=================*/
 
237
        const page_t*   page,   /*!< in: page */
 
238
        ulint           field)  /*!< in: PAGE_FREE, ... */
 
239
        __attribute__((nonnull, pure));
 
240
 
 
241
/*************************************************************//**
 
242
Returns the pointer stored in the given header field, or NULL. */
 
243
#define page_header_get_ptr(page, field)                        \
 
244
        (page_header_get_offs(page, field)                      \
 
245
         ? page + page_header_get_offs(page, field) : NULL)
 
246
/*************************************************************//**
 
247
Sets the pointer stored in the given header field. */
 
248
UNIV_INLINE
 
249
void
 
250
page_header_set_ptr(
 
251
/*================*/
 
252
        page_t*         page,   /*!< in/out: page */
 
253
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
254
                                uncompressed part will be updated, or NULL */
 
255
        ulint           field,  /*!< in/out: PAGE_FREE, ... */
 
256
        const byte*     ptr);   /*!< in: pointer or NULL*/
 
257
#ifndef UNIV_HOTBACKUP
 
258
/*************************************************************//**
 
259
Resets the last insert info field in the page header. Writes to mlog
 
260
about this operation. */
 
261
UNIV_INLINE
 
262
void
 
263
page_header_reset_last_insert(
 
264
/*==========================*/
 
265
        page_t*         page,   /*!< in: page */
 
266
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
267
                                uncompressed part will be updated, or NULL */
 
268
        mtr_t*          mtr);   /*!< in: mtr */
 
269
#endif /* !UNIV_HOTBACKUP */
 
270
/************************************************************//**
 
271
Gets the offset of the first record on the page.
 
272
@return offset of the first record in record list, relative from page */
 
273
UNIV_INLINE
 
274
ulint
 
275
page_get_infimum_offset(
 
276
/*====================*/
 
277
        const page_t*   page);  /*!< in: page which must have record(s) */
 
278
/************************************************************//**
 
279
Gets the offset of the last record on the page.
 
280
@return offset of the last record in record list, relative from page */
 
281
UNIV_INLINE
 
282
ulint
 
283
page_get_supremum_offset(
 
284
/*=====================*/
 
285
        const page_t*   page);  /*!< in: page which must have record(s) */
 
286
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
 
287
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
 
288
/************************************************************//**
 
289
Returns the middle record of record list. If there are an even number
 
290
of records in the list, returns the first record of upper half-list.
 
291
@return middle record */
 
292
UNIV_INTERN
 
293
rec_t*
 
294
page_get_middle_rec(
 
295
/*================*/
 
296
        page_t* page);  /*!< in: page */
 
297
#ifndef UNIV_HOTBACKUP
 
298
/*************************************************************//**
 
299
Compares a data tuple to a physical record. Differs from the function
 
300
cmp_dtuple_rec_with_match in the way that the record must reside on an
 
301
index page, and also page infimum and supremum records can be given in
 
302
the parameter rec. These are considered as the negative infinity and
 
303
the positive infinity in the alphabetical order.
 
304
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
 
305
respectively, when only the common first fields are compared */
 
306
UNIV_INLINE
 
307
int
 
308
page_cmp_dtuple_rec_with_match(
 
309
/*===========================*/
 
310
        const dtuple_t* dtuple, /*!< in: data tuple */
 
311
        const rec_t*    rec,    /*!< in: physical record on a page; may also
 
312
                                be page infimum or supremum, in which case
 
313
                                matched-parameter values below are not
 
314
                                affected */
 
315
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
316
        ulint*          matched_fields, /*!< in/out: number of already completely
 
317
                                matched fields; when function returns
 
318
                                contains the value for current comparison */
 
319
        ulint*          matched_bytes); /*!< in/out: number of already matched
 
320
                                bytes within the first field not completely
 
321
                                matched; when function returns contains the
 
322
                                value for current comparison */
 
323
#endif /* !UNIV_HOTBACKUP */
 
324
/*************************************************************//**
 
325
Gets the page number.
 
326
@return page number */
 
327
UNIV_INLINE
 
328
ulint
 
329
page_get_page_no(
 
330
/*=============*/
 
331
        const page_t*   page);  /*!< in: page */
 
332
/*************************************************************//**
 
333
Gets the tablespace identifier.
 
334
@return space id */
 
335
UNIV_INLINE
 
336
ulint
 
337
page_get_space_id(
 
338
/*==============*/
 
339
        const page_t*   page);  /*!< in: page */
 
340
/*************************************************************//**
 
341
Gets the number of user records on page (the infimum and supremum records
 
342
are not user records).
 
343
@return number of user records */
 
344
UNIV_INLINE
 
345
ulint
 
346
page_get_n_recs(
 
347
/*============*/
 
348
        const page_t*   page);  /*!< in: index page */
 
349
/***************************************************************//**
 
350
Returns the number of records before the given record in chain.
 
351
The number includes infimum and supremum records.
 
352
@return number of records */
 
353
UNIV_INTERN
 
354
ulint
 
355
page_rec_get_n_recs_before(
 
356
/*=======================*/
 
357
        const rec_t*    rec);   /*!< in: the physical record */
 
358
/*************************************************************//**
 
359
Gets the number of records in the heap.
 
360
@return number of user records */
 
361
UNIV_INLINE
 
362
ulint
 
363
page_dir_get_n_heap(
 
364
/*================*/
 
365
        const page_t*   page);  /*!< in: index page */
 
366
/*************************************************************//**
 
367
Sets the number of records in the heap. */
 
368
UNIV_INLINE
 
369
void
 
370
page_dir_set_n_heap(
 
371
/*================*/
 
372
        page_t*         page,   /*!< in/out: index page */
 
373
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
374
                                uncompressed part will be updated, or NULL.
 
375
                                Note that the size of the dense page directory
 
376
                                in the compressed page trailer is
 
377
                                n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
 
378
        ulint           n_heap);/*!< in: number of records */
 
379
/*************************************************************//**
 
380
Gets the number of dir slots in directory.
 
381
@return number of slots */
 
382
UNIV_INLINE
 
383
ulint
 
384
page_dir_get_n_slots(
 
385
/*=================*/
 
386
        const page_t*   page);  /*!< in: index page */
 
387
/*************************************************************//**
 
388
Sets the number of dir slots in directory. */
 
389
UNIV_INLINE
 
390
void
 
391
page_dir_set_n_slots(
 
392
/*=================*/
 
393
        page_t*         page,   /*!< in/out: page */
 
394
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
395
                                uncompressed part will be updated, or NULL */
 
396
        ulint           n_slots);/*!< in: number of slots */
 
397
#ifdef UNIV_DEBUG
 
398
/*************************************************************//**
 
399
Gets pointer to nth directory slot.
 
400
@return pointer to dir slot */
 
401
UNIV_INLINE
 
402
page_dir_slot_t*
 
403
page_dir_get_nth_slot(
 
404
/*==================*/
 
405
        const page_t*   page,   /*!< in: index page */
 
406
        ulint           n);     /*!< in: position */
 
407
#else /* UNIV_DEBUG */
 
408
# define page_dir_get_nth_slot(page, n)         \
 
409
        ((page) + UNIV_PAGE_SIZE - PAGE_DIR     \
 
410
         - (n + 1) * PAGE_DIR_SLOT_SIZE)
 
411
#endif /* UNIV_DEBUG */
 
412
/**************************************************************//**
 
413
Used to check the consistency of a record on a page.
 
414
@return TRUE if succeed */
 
415
UNIV_INLINE
 
416
ibool
 
417
page_rec_check(
 
418
/*===========*/
 
419
        const rec_t*    rec);   /*!< in: record */
 
420
/***************************************************************//**
 
421
Gets the record pointed to by a directory slot.
 
422
@return pointer to record */
 
423
UNIV_INLINE
 
424
const rec_t*
 
425
page_dir_slot_get_rec(
 
426
/*==================*/
 
427
        const page_dir_slot_t*  slot);  /*!< in: directory slot */
 
428
/***************************************************************//**
 
429
This is used to set the record offset in a directory slot. */
 
430
UNIV_INLINE
 
431
void
 
432
page_dir_slot_set_rec(
 
433
/*==================*/
 
434
        page_dir_slot_t* slot,  /*!< in: directory slot */
 
435
        rec_t*           rec);  /*!< in: record on the page */
 
436
/***************************************************************//**
 
437
Gets the number of records owned by a directory slot.
 
438
@return number of records */
 
439
UNIV_INLINE
 
440
ulint
 
441
page_dir_slot_get_n_owned(
 
442
/*======================*/
 
443
        const page_dir_slot_t*  slot);  /*!< in: page directory slot */
 
444
/***************************************************************//**
 
445
This is used to set the owned records field of a directory slot. */
 
446
UNIV_INLINE
 
447
void
 
448
page_dir_slot_set_n_owned(
 
449
/*======================*/
 
450
        page_dir_slot_t*slot,   /*!< in/out: directory slot */
 
451
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
452
        ulint           n);     /*!< in: number of records owned by the slot */
 
453
/************************************************************//**
 
454
Calculates the space reserved for directory slots of a given
 
455
number of records. The exact value is a fraction number
 
456
n * PAGE_DIR_SLOT_SIZE / PAGE_DIR_SLOT_MIN_N_OWNED, and it is
 
457
rounded upwards to an integer. */
 
458
UNIV_INLINE
 
459
ulint
 
460
page_dir_calc_reserved_space(
 
461
/*=========================*/
 
462
        ulint   n_recs);        /*!< in: number of records */
 
463
/***************************************************************//**
 
464
Looks for the directory slot which owns the given record.
 
465
@return the directory slot number */
 
466
UNIV_INTERN
 
467
ulint
 
468
page_dir_find_owner_slot(
 
469
/*=====================*/
 
470
        const rec_t*    rec);   /*!< in: the physical record */
 
471
/************************************************************//**
 
472
Determine whether the page is in new-style compact format.
 
473
@return nonzero if the page is in compact format, zero if it is in
 
474
old-style format */
 
475
UNIV_INLINE
 
476
ulint
 
477
page_is_comp(
 
478
/*=========*/
 
479
        const page_t*   page);  /*!< in: index page */
 
480
/************************************************************//**
 
481
TRUE if the record is on a page in compact format.
 
482
@return nonzero if in compact format */
 
483
UNIV_INLINE
 
484
ulint
 
485
page_rec_is_comp(
 
486
/*=============*/
 
487
        const rec_t*    rec);   /*!< in: record */
 
488
/***************************************************************//**
 
489
Returns the heap number of a record.
 
490
@return heap number */
 
491
UNIV_INLINE
 
492
ulint
 
493
page_rec_get_heap_no(
 
494
/*=================*/
 
495
        const rec_t*    rec);   /*!< in: the physical record */
 
496
/************************************************************//**
 
497
Determine whether the page is a B-tree leaf.
 
498
@return TRUE if the page is a B-tree leaf */
 
499
UNIV_INLINE
 
500
ibool
 
501
page_is_leaf(
 
502
/*=========*/
 
503
        const page_t*   page)   /*!< in: page */
 
504
        __attribute__((nonnull, pure));
 
505
/************************************************************//**
 
506
Gets the pointer to the next record on the page.
 
507
@return pointer to next record */
 
508
UNIV_INLINE
 
509
const rec_t*
 
510
page_rec_get_next_low(
 
511
/*==================*/
 
512
        const rec_t*    rec,    /*!< in: pointer to record */
 
513
        ulint           comp);  /*!< in: nonzero=compact page layout */
 
514
/************************************************************//**
 
515
Gets the pointer to the next record on the page.
 
516
@return pointer to next record */
 
517
UNIV_INLINE
 
518
rec_t*
 
519
page_rec_get_next(
 
520
/*==============*/
 
521
        rec_t*  rec);   /*!< in: pointer to record */
 
522
/************************************************************//**
 
523
Gets the pointer to the next record on the page.
 
524
@return pointer to next record */
 
525
UNIV_INLINE
 
526
const rec_t*
 
527
page_rec_get_next_const(
 
528
/*====================*/
 
529
        const rec_t*    rec);   /*!< in: pointer to record */
 
530
/************************************************************//**
 
531
Sets the pointer to the next record on the page. */
 
532
UNIV_INLINE
 
533
void
 
534
page_rec_set_next(
 
535
/*==============*/
 
536
        rec_t*  rec,    /*!< in: pointer to record,
 
537
                        must not be page supremum */
 
538
        rec_t*  next);  /*!< in: pointer to next record,
 
539
                        must not be page infimum */
 
540
/************************************************************//**
 
541
Gets the pointer to the previous record.
 
542
@return pointer to previous record */
 
543
UNIV_INLINE
 
544
const rec_t*
 
545
page_rec_get_prev_const(
 
546
/*====================*/
 
547
        const rec_t*    rec);   /*!< in: pointer to record, must not be page
 
548
                                infimum */
 
549
/************************************************************//**
 
550
Gets the pointer to the previous record.
 
551
@return pointer to previous record */
 
552
UNIV_INLINE
 
553
rec_t*
 
554
page_rec_get_prev(
 
555
/*==============*/
 
556
        rec_t*          rec);   /*!< in: pointer to record,
 
557
                                must not be page infimum */
 
558
/************************************************************//**
 
559
TRUE if the record is a user record on the page.
 
560
@return TRUE if a user record */
 
561
UNIV_INLINE
 
562
ibool
 
563
page_rec_is_user_rec_low(
 
564
/*=====================*/
 
565
        ulint   offset) /*!< in: record offset on page */
 
566
        __attribute__((const));
 
567
/************************************************************//**
 
568
TRUE if the record is the supremum record on a page.
 
569
@return TRUE if the supremum record */
 
570
UNIV_INLINE
 
571
ibool
 
572
page_rec_is_supremum_low(
 
573
/*=====================*/
 
574
        ulint   offset) /*!< in: record offset on page */
 
575
        __attribute__((const));
 
576
/************************************************************//**
 
577
TRUE if the record is the infimum record on a page.
 
578
@return TRUE if the infimum record */
 
579
UNIV_INLINE
 
580
ibool
 
581
page_rec_is_infimum_low(
 
582
/*====================*/
 
583
        ulint   offset) /*!< in: record offset on page */
 
584
        __attribute__((const));
 
585
 
 
586
/************************************************************//**
 
587
TRUE if the record is a user record on the page.
 
588
@return TRUE if a user record */
 
589
UNIV_INLINE
 
590
ibool
 
591
page_rec_is_user_rec(
 
592
/*=================*/
 
593
        const rec_t*    rec)    /*!< in: record */
 
594
        __attribute__((const));
 
595
/************************************************************//**
 
596
TRUE if the record is the supremum record on a page.
 
597
@return TRUE if the supremum record */
 
598
UNIV_INLINE
 
599
ibool
 
600
page_rec_is_supremum(
 
601
/*=================*/
 
602
        const rec_t*    rec)    /*!< in: record */
 
603
        __attribute__((const));
 
604
 
 
605
/************************************************************//**
 
606
TRUE if the record is the infimum record on a page.
 
607
@return TRUE if the infimum record */
 
608
UNIV_INLINE
 
609
ibool
 
610
page_rec_is_infimum(
 
611
/*================*/
 
612
        const rec_t*    rec)    /*!< in: record */
 
613
        __attribute__((const));
 
614
/***************************************************************//**
 
615
Looks for the record which owns the given record.
 
616
@return the owner record */
 
617
UNIV_INLINE
 
618
rec_t*
 
619
page_rec_find_owner_rec(
 
620
/*====================*/
 
621
        rec_t*  rec);   /*!< in: the physical record */
 
622
/***********************************************************************//**
 
623
This is a low-level operation which is used in a database index creation
 
624
to update the page number of a created B-tree to a data dictionary
 
625
record. */
 
626
UNIV_INTERN
 
627
void
 
628
page_rec_write_index_page_no(
 
629
/*=========================*/
 
630
        rec_t*  rec,    /*!< in: record to update */
 
631
        ulint   i,      /*!< in: index of the field to update */
 
632
        ulint   page_no,/*!< in: value to write */
 
633
        mtr_t*  mtr);   /*!< in: mtr */
 
634
/************************************************************//**
 
635
Returns the maximum combined size of records which can be inserted on top
 
636
of record heap.
 
637
@return maximum combined size for inserted records */
 
638
UNIV_INLINE
 
639
ulint
 
640
page_get_max_insert_size(
 
641
/*=====================*/
 
642
        const page_t*   page,   /*!< in: index page */
 
643
        ulint           n_recs);/*!< in: number of records */
 
644
/************************************************************//**
 
645
Returns the maximum combined size of records which can be inserted on top
 
646
of record heap if page is first reorganized.
 
647
@return maximum combined size for inserted records */
 
648
UNIV_INLINE
 
649
ulint
 
650
page_get_max_insert_size_after_reorganize(
 
651
/*======================================*/
 
652
        const page_t*   page,   /*!< in: index page */
 
653
        ulint           n_recs);/*!< in: number of records */
 
654
/*************************************************************//**
 
655
Calculates free space if a page is emptied.
 
656
@return free space */
 
657
UNIV_INLINE
 
658
ulint
 
659
page_get_free_space_of_empty(
 
660
/*=========================*/
 
661
        ulint   comp)   /*!< in: nonzero=compact page format */
 
662
                __attribute__((const));
 
663
/**********************************************************//**
 
664
Returns the base extra size of a physical record.  This is the
 
665
size of the fixed header, independent of the record size.
 
666
@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
 
667
UNIV_INLINE
 
668
ulint
 
669
page_rec_get_base_extra_size(
 
670
/*=========================*/
 
671
        const rec_t*    rec);   /*!< in: physical record */
 
672
/************************************************************//**
 
673
Returns the sum of the sizes of the records in the record list
 
674
excluding the infimum and supremum records.
 
675
@return data in bytes */
 
676
UNIV_INLINE
 
677
ulint
 
678
page_get_data_size(
 
679
/*===============*/
 
680
        const page_t*   page);  /*!< in: index page */
 
681
/************************************************************//**
 
682
Allocates a block of memory from the head of the free list
 
683
of an index page. */
 
684
UNIV_INLINE
 
685
void
 
686
page_mem_alloc_free(
 
687
/*================*/
 
688
        page_t*         page,   /*!< in/out: index page */
 
689
        page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
 
690
                                space available for inserting the record,
 
691
                                or NULL */
 
692
        rec_t*          next_rec,/*!< in: pointer to the new head of the
 
693
                                free record list */
 
694
        ulint           need);  /*!< in: number of bytes allocated */
 
695
/************************************************************//**
 
696
Allocates a block of memory from the heap of an index page.
 
697
@return pointer to start of allocated buffer, or NULL if allocation fails */
 
698
UNIV_INTERN
 
699
byte*
 
700
page_mem_alloc_heap(
 
701
/*================*/
 
702
        page_t*         page,   /*!< in/out: index page */
 
703
        page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
 
704
                                space available for inserting the record,
 
705
                                or NULL */
 
706
        ulint           need,   /*!< in: total number of bytes needed */
 
707
        ulint*          heap_no);/*!< out: this contains the heap number
 
708
                                of the allocated record
 
709
                                if allocation succeeds */
 
710
/************************************************************//**
 
711
Puts a record to free list. */
 
712
UNIV_INLINE
 
713
void
 
714
page_mem_free(
 
715
/*==========*/
 
716
        page_t*         page,   /*!< in/out: index page */
 
717
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
718
        rec_t*          rec,    /*!< in: pointer to the (origin of) record */
 
719
        dict_index_t*   index,  /*!< in: index of rec */
 
720
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
721
/**********************************************************//**
 
722
Create an uncompressed B-tree index page.
 
723
@return pointer to the page */
 
724
UNIV_INTERN
 
725
page_t*
 
726
page_create(
 
727
/*========*/
 
728
        buf_block_t*    block,          /*!< in: a buffer block where the
 
729
                                        page is created */
 
730
        mtr_t*          mtr,            /*!< in: mini-transaction handle */
 
731
        ulint           comp);          /*!< in: nonzero=compact page format */
 
732
/**********************************************************//**
 
733
Create a compressed B-tree index page.
 
734
@return pointer to the page */
 
735
UNIV_INTERN
 
736
page_t*
 
737
page_create_zip(
 
738
/*============*/
 
739
        buf_block_t*    block,          /*!< in/out: a buffer frame where the
 
740
                                        page is created */
 
741
        dict_index_t*   index,          /*!< in: the index of the page */
 
742
        ulint           level,          /*!< in: the B-tree level of the page */
 
743
        mtr_t*          mtr);           /*!< in: mini-transaction handle */
 
744
 
 
745
/*************************************************************//**
 
746
Differs from page_copy_rec_list_end, because this function does not
 
747
touch the lock table and max trx id on page or compress the page. */
 
748
UNIV_INTERN
 
749
void
 
750
page_copy_rec_list_end_no_locks(
 
751
/*============================*/
 
752
        buf_block_t*    new_block,      /*!< in: index page to copy to */
 
753
        buf_block_t*    block,          /*!< in: index page of rec */
 
754
        rec_t*          rec,            /*!< in: record on page */
 
755
        dict_index_t*   index,          /*!< in: record descriptor */
 
756
        mtr_t*          mtr);           /*!< in: mtr */
 
757
/*************************************************************//**
 
758
Copies records from page to new_page, from the given record onward,
 
759
including that record. Infimum and supremum records are not copied.
 
760
The records are copied to the start of the record list on new_page.
 
761
@return pointer to the original successor of the infimum record on
 
762
new_page, or NULL on zip overflow (new_block will be decompressed) */
 
763
UNIV_INTERN
 
764
rec_t*
 
765
page_copy_rec_list_end(
 
766
/*===================*/
 
767
        buf_block_t*    new_block,      /*!< in/out: index page to copy to */
 
768
        buf_block_t*    block,          /*!< in: index page containing rec */
 
769
        rec_t*          rec,            /*!< in: record on page */
 
770
        dict_index_t*   index,          /*!< in: record descriptor */
 
771
        mtr_t*          mtr)            /*!< in: mtr */
 
772
        __attribute__((nonnull));
 
773
/*************************************************************//**
 
774
Copies records from page to new_page, up to the given record, NOT
 
775
including that record. Infimum and supremum records are not copied.
 
776
The records are copied to the end of the record list on new_page.
 
777
@return pointer to the original predecessor of the supremum record on
 
778
new_page, or NULL on zip overflow (new_block will be decompressed) */
 
779
UNIV_INTERN
 
780
rec_t*
 
781
page_copy_rec_list_start(
 
782
/*=====================*/
 
783
        buf_block_t*    new_block,      /*!< in/out: index page to copy to */
 
784
        buf_block_t*    block,          /*!< in: index page containing rec */
 
785
        rec_t*          rec,            /*!< in: record on page */
 
786
        dict_index_t*   index,          /*!< in: record descriptor */
 
787
        mtr_t*          mtr)            /*!< in: mtr */
 
788
        __attribute__((nonnull));
 
789
/*************************************************************//**
 
790
Deletes records from a page from a given record onward, including that record.
 
791
The infimum and supremum records are not deleted. */
 
792
UNIV_INTERN
 
793
void
 
794
page_delete_rec_list_end(
 
795
/*=====================*/
 
796
        rec_t*          rec,    /*!< in: pointer to record on page */
 
797
        buf_block_t*    block,  /*!< in: buffer block of the page */
 
798
        dict_index_t*   index,  /*!< in: record descriptor */
 
799
        ulint           n_recs, /*!< in: number of records to delete,
 
800
                                or ULINT_UNDEFINED if not known */
 
801
        ulint           size,   /*!< in: the sum of the sizes of the
 
802
                                records in the end of the chain to
 
803
                                delete, or ULINT_UNDEFINED if not known */
 
804
        mtr_t*          mtr)    /*!< in: mtr */
 
805
        __attribute__((nonnull));
 
806
/*************************************************************//**
 
807
Deletes records from page, up to the given record, NOT including
 
808
that record. Infimum and supremum records are not deleted. */
 
809
UNIV_INTERN
 
810
void
 
811
page_delete_rec_list_start(
 
812
/*=======================*/
 
813
        rec_t*          rec,    /*!< in: record on page */
 
814
        buf_block_t*    block,  /*!< in: buffer block of the page */
 
815
        dict_index_t*   index,  /*!< in: record descriptor */
 
816
        mtr_t*          mtr)    /*!< in: mtr */
 
817
        __attribute__((nonnull));
 
818
/*************************************************************//**
 
819
Moves record list end to another page. Moved records include
 
820
split_rec.
 
821
@return TRUE on success; FALSE on compression failure (new_block will
 
822
be decompressed) */
 
823
UNIV_INTERN
 
824
ibool
 
825
page_move_rec_list_end(
 
826
/*===================*/
 
827
        buf_block_t*    new_block,      /*!< in/out: index page where to move */
 
828
        buf_block_t*    block,          /*!< in: index page from where to move */
 
829
        rec_t*          split_rec,      /*!< in: first record to move */
 
830
        dict_index_t*   index,          /*!< in: record descriptor */
 
831
        mtr_t*          mtr)            /*!< in: mtr */
 
832
        __attribute__((nonnull(1, 2, 4, 5)));
 
833
/*************************************************************//**
 
834
Moves record list start to another page. Moved records do not include
 
835
split_rec.
 
836
@return TRUE on success; FALSE on compression failure */
 
837
UNIV_INTERN
 
838
ibool
 
839
page_move_rec_list_start(
 
840
/*=====================*/
 
841
        buf_block_t*    new_block,      /*!< in/out: index page where to move */
 
842
        buf_block_t*    block,          /*!< in/out: page containing split_rec */
 
843
        rec_t*          split_rec,      /*!< in: first record not to move */
 
844
        dict_index_t*   index,          /*!< in: record descriptor */
 
845
        mtr_t*          mtr)            /*!< in: mtr */
 
846
        __attribute__((nonnull(1, 2, 4, 5)));
 
847
/****************************************************************//**
 
848
Splits a directory slot which owns too many records. */
 
849
UNIV_INTERN
 
850
void
 
851
page_dir_split_slot(
 
852
/*================*/
 
853
        page_t*         page,   /*!< in: index page */
 
854
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose
 
855
                                uncompressed part will be written, or NULL */
 
856
        ulint           slot_no)/*!< in: the directory slot */
 
857
        __attribute__((nonnull(1)));
 
858
/*************************************************************//**
 
859
Tries to balance the given directory slot with too few records
 
860
with the upper neighbor, so that there are at least the minimum number
 
861
of records owned by the slot; this may result in the merging of
 
862
two slots. */
 
863
UNIV_INTERN
 
864
void
 
865
page_dir_balance_slot(
 
866
/*==================*/
 
867
        page_t*         page,   /*!< in/out: index page */
 
868
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
869
        ulint           slot_no)/*!< in: the directory slot */
 
870
        __attribute__((nonnull(1)));
 
871
/**********************************************************//**
 
872
Parses a log record of a record list end or start deletion.
 
873
@return end of log record or NULL */
 
874
UNIV_INTERN
 
875
byte*
 
876
page_parse_delete_rec_list(
 
877
/*=======================*/
 
878
        byte            type,   /*!< in: MLOG_LIST_END_DELETE,
 
879
                                MLOG_LIST_START_DELETE,
 
880
                                MLOG_COMP_LIST_END_DELETE or
 
881
                                MLOG_COMP_LIST_START_DELETE */
 
882
        byte*           ptr,    /*!< in: buffer */
 
883
        byte*           end_ptr,/*!< in: buffer end */
 
884
        buf_block_t*    block,  /*!< in/out: buffer block or NULL */
 
885
        dict_index_t*   index,  /*!< in: record descriptor */
 
886
        mtr_t*          mtr);   /*!< in: mtr or NULL */
 
887
/***********************************************************//**
 
888
Parses a redo log record of creating a page.
 
889
@return end of log record or NULL */
 
890
UNIV_INTERN
 
891
byte*
 
892
page_parse_create(
 
893
/*==============*/
 
894
        byte*           ptr,    /*!< in: buffer */
 
895
        byte*           end_ptr,/*!< in: buffer end */
 
896
        ulint           comp,   /*!< in: nonzero=compact page format */
 
897
        buf_block_t*    block,  /*!< in: block or NULL */
 
898
        mtr_t*          mtr);   /*!< in: mtr or NULL */
 
899
/************************************************************//**
 
900
Prints record contents including the data relevant only in
 
901
the index page context. */
 
902
UNIV_INTERN
 
903
void
 
904
page_rec_print(
 
905
/*===========*/
 
906
        const rec_t*    rec,    /*!< in: physical record */
 
907
        const ulint*    offsets);/*!< in: record descriptor */
 
908
/***************************************************************//**
 
909
This is used to print the contents of the directory for
 
910
debugging purposes. */
 
911
UNIV_INTERN
 
912
void
 
913
page_dir_print(
 
914
/*===========*/
 
915
        page_t* page,   /*!< in: index page */
 
916
        ulint   pr_n);  /*!< in: print n first and n last entries */
 
917
/***************************************************************//**
 
918
This is used to print the contents of the page record list for
 
919
debugging purposes. */
 
920
UNIV_INTERN
 
921
void
 
922
page_print_list(
 
923
/*============*/
 
924
        buf_block_t*    block,  /*!< in: index page */
 
925
        dict_index_t*   index,  /*!< in: dictionary index of the page */
 
926
        ulint           pr_n);  /*!< in: print n first and n last entries */
 
927
/***************************************************************//**
 
928
Prints the info in a page header. */
 
929
UNIV_INTERN
 
930
void
 
931
page_header_print(
 
932
/*==============*/
 
933
        const page_t*   page);  /*!< in: index page */
 
934
/***************************************************************//**
 
935
This is used to print the contents of the page for
 
936
debugging purposes. */
 
937
UNIV_INTERN
 
938
void
 
939
page_print(
 
940
/*=======*/
 
941
        buf_block_t*    block,  /*!< in: index page */
 
942
        dict_index_t*   index,  /*!< in: dictionary index of the page */
 
943
        ulint           dn,     /*!< in: print dn first and last entries
 
944
                                in directory */
 
945
        ulint           rn);    /*!< in: print rn first and last records
 
946
                                in directory */
 
947
/***************************************************************//**
 
948
The following is used to validate a record on a page. This function
 
949
differs from rec_validate as it can also check the n_owned field and
 
950
the heap_no field.
 
951
@return TRUE if ok */
 
952
UNIV_INTERN
 
953
ibool
 
954
page_rec_validate(
 
955
/*==============*/
 
956
        rec_t*          rec,    /*!< in: physical record */
 
957
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
958
/***************************************************************//**
 
959
Checks that the first directory slot points to the infimum record and
 
960
the last to the supremum. This function is intended to track if the
 
961
bug fixed in 4.0.14 has caused corruption to users' databases. */
 
962
UNIV_INTERN
 
963
void
 
964
page_check_dir(
 
965
/*===========*/
 
966
        const page_t*   page);  /*!< in: index page */
 
967
/***************************************************************//**
 
968
This function checks the consistency of an index page when we do not
 
969
know the index. This is also resilient so that this should never crash
 
970
even if the page is total garbage.
 
971
@return TRUE if ok */
 
972
UNIV_INTERN
 
973
ibool
 
974
page_simple_validate_old(
 
975
/*=====================*/
 
976
        page_t* page);  /*!< in: old-style index page */
 
977
/***************************************************************//**
 
978
This function checks the consistency of an index page when we do not
 
979
know the index. This is also resilient so that this should never crash
 
980
even if the page is total garbage.
 
981
@return TRUE if ok */
 
982
UNIV_INTERN
 
983
ibool
 
984
page_simple_validate_new(
 
985
/*=====================*/
 
986
        page_t* block); /*!< in: new-style index page */
 
987
/***************************************************************//**
 
988
This function checks the consistency of an index page.
 
989
@return TRUE if ok */
 
990
UNIV_INTERN
 
991
ibool
 
992
page_validate(
 
993
/*==========*/
 
994
        page_t*         page,   /*!< in: index page */
 
995
        dict_index_t*   index); /*!< in: data dictionary index containing
 
996
                                the page record type definition */
 
997
/***************************************************************//**
 
998
Looks in the page record list for a record with the given heap number.
 
999
@return record, NULL if not found */
 
1000
 
 
1001
const rec_t*
 
1002
page_find_rec_with_heap_no(
 
1003
/*=======================*/
 
1004
        const page_t*   page,   /*!< in: index page */
 
1005
        ulint           heap_no);/*!< in: heap number */
 
1006
 
 
1007
#ifdef UNIV_MATERIALIZE
 
1008
#undef UNIV_INLINE
 
1009
#define UNIV_INLINE  UNIV_INLINE_ORIGINAL
 
1010
#endif
 
1011
 
 
1012
#ifndef UNIV_NONINL
 
1013
#include "page0page.ic"
 
1014
#endif
 
1015
 
 
1016
#endif