~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 01:03:01 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913010301-tcvvezipx1124acy
Added calls to the dtrace delete begin/end probes.

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