~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Mark Atwood
  • Date: 2008-10-03 01:39:40 UTC
  • mto: This revision was merged to the branch mainline in revision 437.
  • Revision ID: mark@fallenpegasus.com-20081003013940-mvefjo725dltz41h
rename logging_noop to logging_query

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