~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to storage/innobase/include/btr0btr.ic

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-11-08 11:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20111108113113-3ulw01fvi4vn8m25
Tags: upstream-5.5.17
ImportĀ upstreamĀ versionĀ 5.5.17

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file include/btr0btr.ic
 
21
The B-tree
 
22
 
 
23
Created 6/2/1994 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#include "mach0data.h"
 
27
#ifndef UNIV_HOTBACKUP
 
28
#include "mtr0mtr.h"
 
29
#include "mtr0log.h"
 
30
#include "page0zip.h"
 
31
 
 
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 */
 
37
 
 
38
/**************************************************************//**
 
39
Gets a buffer page and declares its latching order level. */
 
40
UNIV_INLINE
 
41
buf_block_t*
 
42
btr_block_get_func(
 
43
/*===============*/
 
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
#ifdef UNIV_SYNC_DEBUG
 
52
        const dict_index_t*     index,  /*!< in: index tree, may be NULL
 
53
                                        if it is not an insert buffer tree */
 
54
#endif /* UNIV_SYNC_DEBUG */
 
55
        mtr_t*          mtr)            /*!< in/out: mtr */
 
56
{
 
57
        buf_block_t*    block;
 
58
 
 
59
        block = buf_page_get_gen(space, zip_size, page_no, mode,
 
60
                                 NULL, BUF_GET, file, line, mtr);
 
61
 
 
62
        if (mode != RW_NO_LATCH) {
 
63
 
 
64
                buf_block_dbg_add_level(
 
65
                        block, index != NULL && dict_index_is_ibuf(index)
 
66
                        ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
 
67
        }
 
68
 
 
69
        return(block);
 
70
}
 
71
 
 
72
/**************************************************************//**
 
73
Sets the index id field of a page. */
 
74
UNIV_INLINE
 
75
void
 
76
btr_page_set_index_id(
 
77
/*==================*/
 
78
        page_t*         page,   /*!< in: page to be created */
 
79
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
80
                                part will be updated, or NULL */
 
81
        index_id_t      id,     /*!< in: index id */
 
82
        mtr_t*          mtr)    /*!< in: mtr */
 
83
{
 
84
        if (UNIV_LIKELY_NULL(page_zip)) {
 
85
                mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
 
86
                page_zip_write_header(page_zip,
 
87
                                      page + (PAGE_HEADER + PAGE_INDEX_ID),
 
88
                                      8, mtr);
 
89
        } else {
 
90
                mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr);
 
91
        }
 
92
}
 
93
#endif /* !UNIV_HOTBACKUP */
 
94
 
 
95
/**************************************************************//**
 
96
Gets the index id field of a page.
 
97
@return index id */
 
98
UNIV_INLINE
 
99
index_id_t
 
100
btr_page_get_index_id(
 
101
/*==================*/
 
102
        const page_t*   page)   /*!< in: index page */
 
103
{
 
104
        return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
 
105
}
 
106
 
 
107
#ifndef UNIV_HOTBACKUP
 
108
/********************************************************//**
 
109
Gets the node level field in an index page.
 
110
@return level, leaf level == 0 */
 
111
UNIV_INLINE
 
112
ulint
 
113
btr_page_get_level_low(
 
114
/*===================*/
 
115
        const page_t*   page)   /*!< in: index page */
 
116
{
 
117
        ulint   level;
 
118
 
 
119
        ut_ad(page);
 
120
 
 
121
        level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
 
122
 
 
123
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
124
 
 
125
        return(level);
 
126
}
 
127
 
 
128
/********************************************************//**
 
129
Gets the node level field in an index page.
 
130
@return level, leaf level == 0 */
 
131
UNIV_INLINE
 
132
ulint
 
133
btr_page_get_level(
 
134
/*===============*/
 
135
        const page_t*   page,   /*!< in: index page */
 
136
        mtr_t*          mtr __attribute__((unused)))
 
137
                                /*!< in: mini-transaction handle */
 
138
{
 
139
        ut_ad(page && mtr);
 
140
 
 
141
        return(btr_page_get_level_low(page));
 
142
}
 
143
 
 
144
/********************************************************//**
 
145
Sets the node level field in an index page. */
 
146
UNIV_INLINE
 
147
void
 
148
btr_page_set_level(
 
149
/*===============*/
 
150
        page_t*         page,   /*!< in: index page */
 
151
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
152
                                part will be updated, or NULL */
 
153
        ulint           level,  /*!< in: level, leaf level == 0 */
 
154
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
155
{
 
156
        ut_ad(page && mtr);
 
157
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
158
 
 
159
        if (UNIV_LIKELY_NULL(page_zip)) {
 
160
                mach_write_to_2(page + (PAGE_HEADER + PAGE_LEVEL), level);
 
161
                page_zip_write_header(page_zip,
 
162
                                      page + (PAGE_HEADER + PAGE_LEVEL),
 
163
                                      2, mtr);
 
164
        } else {
 
165
                mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level,
 
166
                                 MLOG_2BYTES, mtr);
 
167
        }
 
168
}
 
169
 
 
170
/********************************************************//**
 
171
Gets the next index page number.
 
172
@return next page number */
 
173
UNIV_INLINE
 
174
ulint
 
175
btr_page_get_next(
 
176
/*==============*/
 
177
        const page_t*   page,   /*!< in: index page */
 
178
        mtr_t*          mtr __attribute__((unused)))
 
179
                                /*!< in: mini-transaction handle */
 
180
{
 
181
        ut_ad(page && mtr);
 
182
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
 
183
              || mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_S_FIX));
 
184
 
 
185
        return(mach_read_from_4(page + FIL_PAGE_NEXT));
 
186
}
 
187
 
 
188
/********************************************************//**
 
189
Sets the next index page field. */
 
190
UNIV_INLINE
 
191
void
 
192
btr_page_set_next(
 
193
/*==============*/
 
194
        page_t*         page,   /*!< in: index page */
 
195
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
196
                                part will be updated, or NULL */
 
197
        ulint           next,   /*!< in: next page number */
 
198
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
199
{
 
200
        ut_ad(page && mtr);
 
201
 
 
202
        if (UNIV_LIKELY_NULL(page_zip)) {
 
203
                mach_write_to_4(page + FIL_PAGE_NEXT, next);
 
204
                page_zip_write_header(page_zip, page + FIL_PAGE_NEXT, 4, mtr);
 
205
        } else {
 
206
                mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
 
207
        }
 
208
}
 
209
 
 
210
/********************************************************//**
 
211
Gets the previous index page number.
 
212
@return prev page number */
 
213
UNIV_INLINE
 
214
ulint
 
215
btr_page_get_prev(
 
216
/*==============*/
 
217
        const page_t*   page,   /*!< in: index page */
 
218
        mtr_t*  mtr __attribute__((unused))) /*!< in: mini-transaction handle */
 
219
{
 
220
        ut_ad(page && mtr);
 
221
 
 
222
        return(mach_read_from_4(page + FIL_PAGE_PREV));
 
223
}
 
224
 
 
225
/********************************************************//**
 
226
Sets the previous index page field. */
 
227
UNIV_INLINE
 
228
void
 
229
btr_page_set_prev(
 
230
/*==============*/
 
231
        page_t*         page,   /*!< in: index page */
 
232
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
233
                                part will be updated, or NULL */
 
234
        ulint           prev,   /*!< in: previous page number */
 
235
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
236
{
 
237
        ut_ad(page && mtr);
 
238
 
 
239
        if (UNIV_LIKELY_NULL(page_zip)) {
 
240
                mach_write_to_4(page + FIL_PAGE_PREV, prev);
 
241
                page_zip_write_header(page_zip, page + FIL_PAGE_PREV, 4, mtr);
 
242
        } else {
 
243
                mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
 
244
        }
 
245
}
 
246
 
 
247
/**************************************************************//**
 
248
Gets the child node file address in a node pointer.
 
249
NOTE: the offsets array must contain all offsets for the record since
 
250
we read the last field according to offsets and assume that it contains
 
251
the child page number. In other words offsets must have been retrieved
 
252
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
 
253
@return child node address */
 
254
UNIV_INLINE
 
255
ulint
 
256
btr_node_ptr_get_child_page_no(
 
257
/*===========================*/
 
258
        const rec_t*    rec,    /*!< in: node pointer record */
 
259
        const ulint*    offsets)/*!< in: array returned by rec_get_offsets() */
 
260
{
 
261
        const byte*     field;
 
262
        ulint           len;
 
263
        ulint           page_no;
 
264
 
 
265
        ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
 
266
 
 
267
        /* The child address is in the last field */
 
268
        field = rec_get_nth_field(rec, offsets,
 
269
                                  rec_offs_n_fields(offsets) - 1, &len);
 
270
 
 
271
        ut_ad(len == 4);
 
272
 
 
273
        page_no = mach_read_from_4(field);
 
274
 
 
275
        if (UNIV_UNLIKELY(page_no == 0)) {
 
276
                fprintf(stderr,
 
277
                        "InnoDB: a nonsensical page number 0"
 
278
                        " in a node ptr record at offset %lu\n",
 
279
                        (ulong) page_offset(rec));
 
280
                buf_page_print(page_align(rec), 0);
 
281
        }
 
282
 
 
283
        return(page_no);
 
284
}
 
285
 
 
286
/**************************************************************//**
 
287
Releases the latches on a leaf page and bufferunfixes it. */
 
288
UNIV_INLINE
 
289
void
 
290
btr_leaf_page_release(
 
291
/*==================*/
 
292
        buf_block_t*    block,          /*!< in: buffer block */
 
293
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF or
 
294
                                        BTR_MODIFY_LEAF */
 
295
        mtr_t*          mtr)            /*!< in: mtr */
 
296
{
 
297
        ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
 
298
        ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
 
299
 
 
300
        mtr_memo_release(mtr, block,
 
301
                         latch_mode == BTR_SEARCH_LEAF
 
302
                         ? MTR_MEMO_PAGE_S_FIX
 
303
                         : MTR_MEMO_PAGE_X_FIX);
 
304
}
 
305
#endif /* !UNIV_HOTBACKUP */