1
/*****************************************************************************
3
Copyright (C) 1994, 2010, Innobase Oy. All Rights Reserved.
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.
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.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/btr0btr.ic
23
Created 6/2/1994 Heikki Tuuri
24
*******************************************************/
26
#include "mach0data.h"
27
#ifndef UNIV_HOTBACKUP
32
#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
33
(not really a hard limit).
34
Used in debug assertions
35
in btr_page_set_level and
36
btr_page_get_level_low */
38
/**************************************************************//**
39
Gets a buffer page and declares its latching order level. */
44
ulint space, /*!< in: space id */
45
ulint zip_size, /*!< in: compressed page size in bytes
46
or 0 for uncompressed pages */
47
ulint page_no, /*!< in: page number */
48
ulint mode, /*!< in: latch mode */
49
const char* file, /*!< in: file name */
50
ulint line, /*!< in: line where called */
51
mtr_t* mtr) /*!< in/out: mtr */
55
block = buf_page_get_gen(space, zip_size, page_no, mode,
56
NULL, BUF_GET, file, line, mtr);
58
if (mode != RW_NO_LATCH) {
60
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
66
/**************************************************************//**
67
Sets the index id field of a page. */
70
btr_page_set_index_id(
71
/*==================*/
72
page_t* page, /*!< in: page to be created */
73
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
74
part will be updated, or NULL */
75
index_id_t id, /*!< in: index id */
76
mtr_t* mtr) /*!< in: mtr */
78
if (UNIV_LIKELY_NULL(page_zip)) {
79
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
80
page_zip_write_header(page_zip,
81
page + (PAGE_HEADER + PAGE_INDEX_ID),
84
mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr);
87
#endif /* !UNIV_HOTBACKUP */
89
/**************************************************************//**
90
Gets the index id field of a page.
94
btr_page_get_index_id(
95
/*==================*/
96
const page_t* page) /*!< in: index page */
98
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
101
#ifndef UNIV_HOTBACKUP
102
/********************************************************//**
103
Gets the node level field in an index page.
104
@return level, leaf level == 0 */
107
btr_page_get_level_low(
108
/*===================*/
109
const page_t* page) /*!< in: index page */
115
level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
117
ut_ad(level <= BTR_MAX_NODE_LEVEL);
122
/********************************************************//**
123
Gets the node level field in an index page.
124
@return level, leaf level == 0 */
129
const page_t* page, /*!< in: index page */
130
mtr_t* mtr __attribute__((unused)))
131
/*!< in: mini-transaction handle */
136
return(btr_page_get_level_low(page));
139
/********************************************************//**
140
Sets the node level field in an index page. */
145
page_t* page, /*!< in: index page */
146
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
147
part will be updated, or NULL */
148
ulint level, /*!< in: level, leaf level == 0 */
149
mtr_t* mtr) /*!< in: mini-transaction handle */
152
ut_ad(level <= BTR_MAX_NODE_LEVEL);
154
if (UNIV_LIKELY_NULL(page_zip)) {
155
mach_write_to_2(page + (PAGE_HEADER + PAGE_LEVEL), level);
156
page_zip_write_header(page_zip,
157
page + (PAGE_HEADER + PAGE_LEVEL),
160
mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level,
165
/********************************************************//**
166
Gets the next index page number.
167
@return next page number */
172
const page_t* page, /*!< in: index page */
173
mtr_t* mtr __attribute__((unused)))
174
/*!< in: mini-transaction handle */
178
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
179
|| mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_S_FIX));
181
return(mach_read_from_4(page + FIL_PAGE_NEXT));
184
/********************************************************//**
185
Sets the next index page field. */
190
page_t* page, /*!< in: index page */
191
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
192
part will be updated, or NULL */
193
ulint next, /*!< in: next page number */
194
mtr_t* mtr) /*!< in: mini-transaction handle */
198
if (UNIV_LIKELY_NULL(page_zip)) {
199
mach_write_to_4(page + FIL_PAGE_NEXT, next);
200
page_zip_write_header(page_zip, page + FIL_PAGE_NEXT, 4, mtr);
202
mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
206
/********************************************************//**
207
Gets the previous index page number.
208
@return prev page number */
213
const page_t* page, /*!< in: index page */
214
mtr_t* mtr __attribute__((unused))) /*!< in: mini-transaction handle */
219
return(mach_read_from_4(page + FIL_PAGE_PREV));
222
/********************************************************//**
223
Sets the previous index page field. */
228
page_t* page, /*!< in: index page */
229
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
230
part will be updated, or NULL */
231
ulint prev, /*!< in: previous page number */
232
mtr_t* mtr) /*!< in: mini-transaction handle */
236
if (UNIV_LIKELY_NULL(page_zip)) {
237
mach_write_to_4(page + FIL_PAGE_PREV, prev);
238
page_zip_write_header(page_zip, page + FIL_PAGE_PREV, 4, mtr);
240
mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
244
/**************************************************************//**
245
Gets the child node file address in a node pointer.
246
NOTE: the offsets array must contain all offsets for the record since
247
we read the last field according to offsets and assume that it contains
248
the child page number. In other words offsets must have been retrieved
249
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
250
@return child node address */
253
btr_node_ptr_get_child_page_no(
254
/*===========================*/
255
const rec_t* rec, /*!< in: node pointer record */
256
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
262
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
264
/* The child address is in the last field */
265
field = rec_get_nth_field(rec, offsets,
266
rec_offs_n_fields(offsets) - 1, &len);
270
page_no = mach_read_from_4(field);
272
if (UNIV_UNLIKELY(page_no == 0)) {
274
"InnoDB: a nonsensical page number 0"
275
" in a node ptr record at offset %lu\n",
276
(ulong) page_offset(rec));
277
buf_page_print(page_align(rec), 0);
283
/**************************************************************//**
284
Releases the latches on a leaf page and bufferunfixes it. */
287
btr_leaf_page_release(
288
/*==================*/
289
buf_block_t* block, /*!< in: buffer block */
290
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
292
mtr_t* mtr) /*!< in: mtr */
294
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
295
ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
297
mtr_memo_release(mtr, block,
298
latch_mode == BTR_SEARCH_LEAF
299
? MTR_MEMO_PAGE_S_FIX
300
: MTR_MEMO_PAGE_X_FIX);
302
#endif /* !UNIV_HOTBACKUP */