~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2009-09-30 07:01:32 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20090930070132-b1ol1xu1rpajdddy
Small namespace cleanup.

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