~stewart/haildb/trunk

« back to all changes in this revision

Viewing changes to include/btr0btr.h

  • Committer: Stewart Smith
  • Date: 2010-04-09 07:57:43 UTC
  • Revision ID: stewart@flamingspork.com-20100409075743-jfh1oml3el1uouvh
Embedded InnoDB 1.0.0 released

2009-04-21      The InnoDB Team

        Embedded InnoDB 1.0.0 released

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/******************************************************
 
20
The B-tree
 
21
 
 
22
Created 6/2/1994 Heikki Tuuri
 
23
*******************************************************/
 
24
 
 
25
#ifndef btr0btr_h
 
26
#define btr0btr_h
 
27
 
 
28
#include "univ.i"
 
29
 
 
30
#include "dict0dict.h"
 
31
#include "data0data.h"
 
32
#include "page0cur.h"
 
33
#include "mtr0mtr.h"
 
34
#include "btr0types.h"
 
35
 
 
36
#ifndef UNIV_HOTBACKUP
 
37
/* Maximum record size which can be stored on a page, without using the
 
38
special big record storage structure */
 
39
 
 
40
#define BTR_PAGE_MAX_REC_SIZE   (UNIV_PAGE_SIZE / 2 - 200)
 
41
 
 
42
/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
 
43
such; none of the tree operations avoid producing trees bigger than this. It
 
44
is instead a "max depth that other code must work with", useful for e.g.
 
45
fixed-size arrays that must store some information about each level in a
 
46
tree. In other words: if a B-tree with bigger depth than this is
 
47
encountered, it is not acceptable for it to lead to mysterious memory
 
48
corruption, but it is acceptable for the program to die with a clear assert
 
49
failure. */
 
50
#define BTR_MAX_LEVELS          100
 
51
 
 
52
/* Latching modes for btr_cur_search_to_nth_level(). */
 
53
#define BTR_SEARCH_LEAF         RW_S_LATCH
 
54
#define BTR_MODIFY_LEAF         RW_X_LATCH
 
55
#define BTR_NO_LATCHES          RW_NO_LATCH
 
56
#define BTR_MODIFY_TREE         33
 
57
#define BTR_CONT_MODIFY_TREE    34
 
58
#define BTR_SEARCH_PREV         35
 
59
#define BTR_MODIFY_PREV         36
 
60
 
 
61
/* If this is ORed to the latch mode, it means that the search tuple will be
 
62
inserted to the index, at the searched position */
 
63
#define BTR_INSERT              512
 
64
 
 
65
/* This flag ORed to latch mode says that we do the search in query
 
66
optimization */
 
67
#define BTR_ESTIMATE            1024
 
68
 
 
69
/* This flag ORed to latch mode says that we can ignore possible
 
70
UNIQUE definition on secondary indexes when we decide if we can use the
 
71
insert buffer to speed up inserts */
 
72
#define BTR_IGNORE_SEC_UNIQUE   2048
 
73
 
 
74
/******************************************************************
 
75
Gets the root node of a tree and x-latches it. */
 
76
UNIV_INTERN
 
77
page_t*
 
78
btr_root_get(
 
79
/*=========*/
 
80
                                /* out: root page, x-latched */
 
81
        dict_index_t*   index,  /* in: index tree */
 
82
        mtr_t*          mtr);   /* in: mtr */
 
83
/******************************************************************
 
84
Gets a buffer page and declares its latching order level. */
 
85
UNIV_INLINE
 
86
buf_block_t*
 
87
btr_block_get(
 
88
/*==========*/
 
89
        ulint   space,          /* in: space id */
 
90
        ulint   zip_size,       /* in: compressed page size in bytes
 
91
                                or 0 for uncompressed pages */
 
92
        ulint   page_no,        /* in: page number */
 
93
        ulint   mode,           /* in: latch mode */
 
94
        mtr_t*  mtr);           /* in: mtr */
 
95
/******************************************************************
 
96
Gets a buffer page and declares its latching order level. */
 
97
UNIV_INLINE
 
98
page_t*
 
99
btr_page_get(
 
100
/*=========*/
 
101
        ulint   space,          /* in: space id */
 
102
        ulint   zip_size,       /* in: compressed page size in bytes
 
103
                                or 0 for uncompressed pages */
 
104
        ulint   page_no,        /* in: page number */
 
105
        ulint   mode,           /* in: latch mode */
 
106
        mtr_t*  mtr);           /* in: mtr */
 
107
#endif /* !UNIV_HOTBACKUP */
 
108
/******************************************************************
 
109
Gets the index id field of a page. */
 
110
UNIV_INLINE
 
111
dulint
 
112
btr_page_get_index_id(
 
113
/*==================*/
 
114
                                /* out: index id */
 
115
        const page_t*   page);  /* in: index page */
 
116
#ifndef UNIV_HOTBACKUP
 
117
/************************************************************
 
118
Gets the node level field in an index page. */
 
119
UNIV_INLINE
 
120
ulint
 
121
btr_page_get_level_low(
 
122
/*===================*/
 
123
                                /* out: level, leaf level == 0 */
 
124
        const page_t*   page);  /* in: index page */
 
125
/************************************************************
 
126
Gets the node level field in an index page. */
 
127
UNIV_INLINE
 
128
ulint
 
129
btr_page_get_level(
 
130
/*===============*/
 
131
                                /* out: level, leaf level == 0 */
 
132
        const page_t*   page,   /* in: index page */
 
133
        mtr_t*          mtr);   /* in: mini-transaction handle */
 
134
/************************************************************
 
135
Gets the next index page number. */
 
136
UNIV_INLINE
 
137
ulint
 
138
btr_page_get_next(
 
139
/*==============*/
 
140
                                /* out: next page number */
 
141
        const page_t*   page,   /* in: index page */
 
142
        mtr_t*          mtr);   /* in: mini-transaction handle */
 
143
/************************************************************
 
144
Gets the previous index page number. */
 
145
UNIV_INLINE
 
146
ulint
 
147
btr_page_get_prev(
 
148
/*==============*/
 
149
                                /* out: prev page number */
 
150
        const page_t*   page,   /* in: index page */
 
151
        mtr_t*          mtr);   /* in: mini-transaction handle */
 
152
/*****************************************************************
 
153
Gets pointer to the previous user record in the tree. It is assumed
 
154
that the caller has appropriate latches on the page and its neighbor. */
 
155
UNIV_INTERN
 
156
rec_t*
 
157
btr_get_prev_user_rec(
 
158
/*==================*/
 
159
                        /* out: previous user record, NULL if there is none */
 
160
        rec_t*  rec,    /* in: record on leaf level */
 
161
        mtr_t*  mtr);   /* in: mtr holding a latch on the page, and if
 
162
                        needed, also to the previous page */
 
163
/*****************************************************************
 
164
Gets pointer to the next user record in the tree. It is assumed
 
165
that the caller has appropriate latches on the page and its neighbor. */
 
166
UNIV_INTERN
 
167
rec_t*
 
168
btr_get_next_user_rec(
 
169
/*==================*/
 
170
                        /* out: next user record, NULL if there is none */
 
171
        rec_t*  rec,    /* in: record on leaf level */
 
172
        mtr_t*  mtr);   /* in: mtr holding a latch on the page, and if
 
173
                        needed, also to the next page */
 
174
/******************************************************************
 
175
Releases the latch on a leaf page and bufferunfixes it. */
 
176
UNIV_INLINE
 
177
void
 
178
btr_leaf_page_release(
 
179
/*==================*/
 
180
        buf_block_t*    block,          /* in: buffer block */
 
181
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF or
 
182
                                        BTR_MODIFY_LEAF */
 
183
        mtr_t*          mtr);           /* in: mtr */
 
184
/******************************************************************
 
185
Gets the child node file address in a node pointer. */
 
186
UNIV_INLINE
 
187
ulint
 
188
btr_node_ptr_get_child_page_no(
 
189
/*===========================*/
 
190
                                /* out: child node address */
 
191
        const rec_t*    rec,    /* in: node pointer record */
 
192
        const ulint*    offsets);/* in: array returned by rec_get_offsets() */
 
193
/****************************************************************
 
194
Creates the root node for a new index tree. */
 
195
UNIV_INTERN
 
196
ulint
 
197
btr_create(
 
198
/*=======*/
 
199
                                /* out: page number of the created root,
 
200
                                FIL_NULL if did not succeed */
 
201
        ulint           type,   /* in: type of the index */
 
202
        ulint           space,  /* in: space where created */
 
203
        ulint           zip_size,/* in: compressed page size in bytes
 
204
                                or 0 for uncompressed pages */
 
205
        dulint          index_id,/* in: index id */
 
206
        dict_index_t*   index,  /* in: index */
 
207
        mtr_t*          mtr);   /* in: mini-transaction handle */
 
208
/****************************************************************
 
209
Frees a B-tree except the root page, which MUST be freed after this
 
210
by calling btr_free_root. */
 
211
UNIV_INTERN
 
212
void
 
213
btr_free_but_not_root(
 
214
/*==================*/
 
215
        ulint   space,          /* in: space where created */
 
216
        ulint   zip_size,       /* in: compressed page size in bytes
 
217
                                or 0 for uncompressed pages */
 
218
        ulint   root_page_no);  /* in: root page number */
 
219
/****************************************************************
 
220
Frees the B-tree root page. Other tree MUST already have been freed. */
 
221
UNIV_INTERN
 
222
void
 
223
btr_free_root(
 
224
/*==========*/
 
225
        ulint   space,          /* in: space where created */
 
226
        ulint   zip_size,       /* in: compressed page size in bytes
 
227
                                or 0 for uncompressed pages */
 
228
        ulint   root_page_no,   /* in: root page number */
 
229
        mtr_t*  mtr);           /* in: a mini-transaction which has already
 
230
                                been started */
 
231
/*****************************************************************
 
232
Makes tree one level higher by splitting the root, and inserts
 
233
the tuple. It is assumed that mtr contains an x-latch on the tree.
 
234
NOTE that the operation of this function must always succeed,
 
235
we cannot reverse it: therefore enough free disk space must be
 
236
guaranteed to be available before this function is called. */
 
237
UNIV_INTERN
 
238
rec_t*
 
239
btr_root_raise_and_insert(
 
240
/*======================*/
 
241
                                /* out: inserted record */
 
242
        btr_cur_t*      cursor, /* in: cursor at which to insert: must be
 
243
                                on the root page; when the function returns,
 
244
                                the cursor is positioned on the predecessor
 
245
                                of the inserted record */
 
246
        const dtuple_t* tuple,  /* in: tuple to insert */
 
247
        ulint           n_ext,  /* in: number of externally stored columns */
 
248
        mtr_t*          mtr);   /* in: mtr */
 
249
/*****************************************************************
 
250
Reorganizes an index page.
 
251
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
 
252
page of a non-clustered index, the caller must update the insert
 
253
buffer free bits in the same mini-transaction in such a way that the
 
254
modification will be redo-logged. */
 
255
UNIV_INTERN
 
256
ibool
 
257
btr_page_reorganize(
 
258
/*================*/
 
259
                                /* out: TRUE on success, FALSE on failure */
 
260
        buf_block_t*    block,  /* in: page to be reorganized */
 
261
        dict_index_t*   index,  /* in: record descriptor */
 
262
        mtr_t*          mtr);   /* in: mtr */
 
263
/*****************************************************************
 
264
Decides if the page should be split at the convergence point of
 
265
inserts converging to left. */
 
266
UNIV_INTERN
 
267
ibool
 
268
btr_page_get_split_rec_to_left(
 
269
/*===========================*/
 
270
                                /* out: TRUE if split recommended */
 
271
        btr_cur_t*      cursor, /* in: cursor at which to insert */
 
272
        rec_t**         split_rec);/* out: if split recommended,
 
273
                                the first record on upper half page,
 
274
                                or NULL if tuple should be first */
 
275
/*****************************************************************
 
276
Decides if the page should be split at the convergence point of
 
277
inserts converging to right. */
 
278
UNIV_INTERN
 
279
ibool
 
280
btr_page_get_split_rec_to_right(
 
281
/*============================*/
 
282
                                /* out: TRUE if split recommended */
 
283
        btr_cur_t*      cursor, /* in: cursor at which to insert */
 
284
        rec_t**         split_rec);/* out: if split recommended,
 
285
                                the first record on upper half page,
 
286
                                or NULL if tuple should be first */
 
287
/*****************************************************************
 
288
Splits an index page to halves and inserts the tuple. It is assumed
 
289
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
 
290
is released within this function! NOTE that the operation of this
 
291
function must always succeed, we cannot reverse it: therefore
 
292
enough free disk space must be guaranteed to be available before
 
293
this function is called. */
 
294
UNIV_INTERN
 
295
rec_t*
 
296
btr_page_split_and_insert(
 
297
/*======================*/
 
298
                                /* out: inserted record; NOTE: the tree
 
299
                                x-latch is released! NOTE: 2 free disk
 
300
                                pages must be available! */
 
301
        btr_cur_t*      cursor, /* in: cursor at which to insert; when the
 
302
                                function returns, the cursor is positioned
 
303
                                on the predecessor of the inserted record */
 
304
        const dtuple_t* tuple,  /* in: tuple to insert */
 
305
        ulint           n_ext,  /* in: number of externally stored columns */
 
306
        mtr_t*          mtr);   /* in: mtr */
 
307
/***********************************************************
 
308
Inserts a data tuple to a tree on a non-leaf level. It is assumed
 
309
that mtr holds an x-latch on the tree. */
 
310
UNIV_INTERN
 
311
void
 
312
btr_insert_on_non_leaf_level(
 
313
/*=========================*/
 
314
        dict_index_t*   index,  /* in: index */
 
315
        ulint           level,  /* in: level, must be > 0 */
 
316
        dtuple_t*       tuple,  /* in: the record to be inserted */
 
317
        mtr_t*          mtr);   /* in: mtr */
 
318
#endif /* !UNIV_HOTBACKUP */
 
319
/********************************************************************
 
320
Sets a record as the predefined minimum record. */
 
321
UNIV_INTERN
 
322
void
 
323
btr_set_min_rec_mark(
 
324
/*=================*/
 
325
        rec_t*  rec,    /* in/out: record */
 
326
        mtr_t*  mtr);   /* in: mtr */
 
327
#ifndef UNIV_HOTBACKUP
 
328
/*****************************************************************
 
329
Deletes on the upper level the node pointer to a page. */
 
330
UNIV_INTERN
 
331
void
 
332
btr_node_ptr_delete(
 
333
/*================*/
 
334
        dict_index_t*   index,  /* in: index tree */
 
335
        buf_block_t*    block,  /* in: page whose node pointer is deleted */
 
336
        mtr_t*          mtr);   /* in: mtr */
 
337
#ifdef UNIV_DEBUG
 
338
/****************************************************************
 
339
Checks that the node pointer to a page is appropriate. */
 
340
UNIV_INTERN
 
341
ibool
 
342
btr_check_node_ptr(
 
343
/*===============*/
 
344
                                /* out: TRUE */
 
345
        dict_index_t*   index,  /* in: index tree */
 
346
        buf_block_t*    block,  /* in: index page */
 
347
        mtr_t*          mtr);   /* in: mtr */
 
348
#endif /* UNIV_DEBUG */
 
349
/*****************************************************************
 
350
Tries to merge the page first to the left immediate brother if such a
 
351
brother exists, and the node pointers to the current page and to the
 
352
brother reside on the same page. If the left brother does not satisfy these
 
353
conditions, looks at the right brother. If the page is the only one on that
 
354
level lifts the records of the page to the father page, thus reducing the
 
355
tree height. It is assumed that mtr holds an x-latch on the tree and on the
 
356
page. If cursor is on the leaf level, mtr must also hold x-latches to
 
357
the brothers, if they exist. */
 
358
UNIV_INTERN
 
359
ibool
 
360
btr_compress(
 
361
/*=========*/
 
362
                                /* out: TRUE on success */
 
363
        btr_cur_t*      cursor, /* in: cursor on the page to merge or lift;
 
364
                                the page must not be empty: in record delete
 
365
                                use btr_discard_page if the page would become
 
366
                                empty */
 
367
        mtr_t*          mtr);   /* in: mtr */
 
368
/*****************************************************************
 
369
Discards a page from a B-tree. This is used to remove the last record from
 
370
a B-tree page: the whole page must be removed at the same time. This cannot
 
371
be used for the root page, which is allowed to be empty. */
 
372
UNIV_INTERN
 
373
void
 
374
btr_discard_page(
 
375
/*=============*/
 
376
        btr_cur_t*      cursor, /* in: cursor on the page to discard: not on
 
377
                                the root page */
 
378
        mtr_t*          mtr);   /* in: mtr */
 
379
#endif /* !UNIV_HOTBACKUP */
 
380
/********************************************************************
 
381
Parses the redo log record for setting an index record as the predefined
 
382
minimum record. */
 
383
UNIV_INTERN
 
384
byte*
 
385
btr_parse_set_min_rec_mark(
 
386
/*=======================*/
 
387
                        /* out: end of log record or NULL */
 
388
        byte*   ptr,    /* in: buffer */
 
389
        byte*   end_ptr,/* in: buffer end */
 
390
        ulint   comp,   /* in: nonzero=compact page format */
 
391
        page_t* page,   /* in: page or NULL */
 
392
        mtr_t*  mtr);   /* in: mtr or NULL */
 
393
/***************************************************************
 
394
Parses a redo log record of reorganizing a page. */
 
395
UNIV_INTERN
 
396
byte*
 
397
btr_parse_page_reorganize(
 
398
/*======================*/
 
399
                                /* out: end of log record or NULL */
 
400
        byte*           ptr,    /* in: buffer */
 
401
        byte*           end_ptr,/* in: buffer end */
 
402
        dict_index_t*   index,  /* in: record descriptor */
 
403
        buf_block_t*    block,  /* in: page to be reorganized, or NULL */
 
404
        mtr_t*          mtr);   /* in: mtr or NULL */
 
405
#ifndef UNIV_HOTBACKUP
 
406
/******************************************************************
 
407
Gets the number of pages in a B-tree. */
 
408
UNIV_INTERN
 
409
ulint
 
410
btr_get_size(
 
411
/*=========*/
 
412
                                /* out: number of pages */
 
413
        dict_index_t*   index,  /* in: index */
 
414
        ulint           flag);  /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
 
415
/******************************************************************
 
416
Allocates a new file page to be used in an index tree. NOTE: we assume
 
417
that the caller has made the reservation for free extents! */
 
418
UNIV_INTERN
 
419
buf_block_t*
 
420
btr_page_alloc(
 
421
/*===========*/
 
422
                                        /* out: new allocated block, x-latched;
 
423
                                        NULL if out of space */
 
424
        dict_index_t*   index,          /* in: index tree */
 
425
        ulint           hint_page_no,   /* in: hint of a good page */
 
426
        byte            file_direction, /* in: direction where a possible
 
427
                                        page split is made */
 
428
        ulint           level,          /* in: level where the page is placed
 
429
                                        in the tree */
 
430
        mtr_t*          mtr);           /* in: mtr */
 
431
/******************************************************************
 
432
Frees a file page used in an index tree. NOTE: cannot free field external
 
433
storage pages because the page must contain info on its level. */
 
434
UNIV_INTERN
 
435
void
 
436
btr_page_free(
 
437
/*==========*/
 
438
        dict_index_t*   index,  /* in: index tree */
 
439
        buf_block_t*    block,  /* in: block to be freed, x-latched */
 
440
        mtr_t*          mtr);   /* in: mtr */
 
441
/******************************************************************
 
442
Frees a file page used in an index tree. Can be used also to BLOB
 
443
external storage pages, because the page level 0 can be given as an
 
444
argument. */
 
445
UNIV_INTERN
 
446
void
 
447
btr_page_free_low(
 
448
/*==============*/
 
449
        dict_index_t*   index,  /* in: index tree */
 
450
        buf_block_t*    block,  /* in: block to be freed, x-latched */
 
451
        ulint           level,  /* in: page level */
 
452
        mtr_t*          mtr);   /* in: mtr */
 
453
#ifdef UNIV_BTR_PRINT
 
454
/*****************************************************************
 
455
Prints size info of a B-tree. */
 
456
UNIV_INTERN
 
457
void
 
458
btr_print_size(
 
459
/*===========*/
 
460
        dict_index_t*   index); /* in: index tree */
 
461
/******************************************************************
 
462
Prints directories and other info of all nodes in the index. */
 
463
UNIV_INTERN
 
464
void
 
465
btr_print_index(
 
466
/*============*/
 
467
        dict_index_t*   index,  /* in: index */
 
468
        ulint           width); /* in: print this many entries from start
 
469
                                and end */
 
470
#endif /* UNIV_BTR_PRINT */
 
471
/****************************************************************
 
472
Checks the size and number of fields in a record based on the definition of
 
473
the index. */
 
474
UNIV_INTERN
 
475
ibool
 
476
btr_index_rec_validate(
 
477
/*===================*/
 
478
                                                /* out: TRUE if ok */
 
479
        const rec_t*            rec,            /* in: index record */
 
480
        const dict_index_t*     index,          /* in: index */
 
481
        ibool                   dump_on_error); /* in: TRUE if the function
 
482
                                                should print hex dump of record
 
483
                                                and page on error */
 
484
/******************************************************************
 
485
Checks the consistency of an index tree. */
 
486
UNIV_INTERN
 
487
ibool
 
488
btr_validate_index(
 
489
/*===============*/
 
490
                                /* out: TRUE if ok */
 
491
        dict_index_t*   index,  /* in: index */
 
492
        trx_t*          trx);   /* in: transaction or NULL */
 
493
 
 
494
#define BTR_N_LEAF_PAGES        1
 
495
#define BTR_TOTAL_SIZE          2
 
496
#endif /* !UNIV_HOTBACKUP */
 
497
 
 
498
#ifndef UNIV_NONINL
 
499
#include "btr0btr.ic"
 
500
#endif
 
501
 
 
502
#endif