~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Moriyoshi Koizumi
  • Date: 2008-11-15 18:36:31 UTC
  • mto: (584.1.5 devel)
  • mto: This revision was merged to the branch mainline in revision 588.
  • Revision ID: mozo@mozo.jp-20081115183631-81d0clowyot42mk7
Incorporating changes proposed by mtaylor.

Show diffs side-by-side

added added

removed removed

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