~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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
@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(
 
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
        mtr_t*  mtr)            /*!< in: mtr */
 
50
{
 
51
        buf_block_t*    block;
 
52
 
 
53
        block = buf_page_get(space, zip_size, page_no, mode, mtr);
 
54
 
 
55
        if (mode != RW_NO_LATCH) {
 
56
 
 
57
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
58
        }
 
59
 
 
60
        return(block);
 
61
}
 
62
 
 
63
/**************************************************************//**
 
64
Gets a buffer page and declares its latching order level. */
 
65
UNIV_INLINE
 
66
page_t*
 
67
btr_page_get(
 
68
/*=========*/
 
69
        ulint   space,          /*!< in: space id */
 
70
        ulint   zip_size,       /*!< in: compressed page size in bytes
 
71
                                or 0 for uncompressed pages */
 
72
        ulint   page_no,        /*!< in: page number */
 
73
        ulint   mode,           /*!< in: latch mode */
 
74
        mtr_t*  mtr)            /*!< in: mtr */
 
75
{
 
76
        return(buf_block_get_frame(btr_block_get(space, zip_size, page_no,
 
77
                                                 mode, mtr)));
 
78
}
 
79
 
 
80
/**************************************************************//**
 
81
Sets the index id field of a page. */
 
82
UNIV_INLINE
 
83
void
 
84
btr_page_set_index_id(
 
85
/*==================*/
 
86
        page_t*         page,   /*!< in: page to be created */
 
87
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
88
                                part will be updated, or NULL */
 
89
        dulint          id,     /*!< in: index id */
 
90
        mtr_t*          mtr)    /*!< in: mtr */
 
91
{
 
92
        if (UNIV_LIKELY_NULL(page_zip)) {
 
93
                mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
 
94
                page_zip_write_header(page_zip,
 
95
                                      page + (PAGE_HEADER + PAGE_INDEX_ID),
 
96
                                      8, mtr);
 
97
        } else {
 
98
                mlog_write_dulint(page + (PAGE_HEADER + PAGE_INDEX_ID),
 
99
                                  id, mtr);
 
100
        }
 
101
}
 
102
#endif /* !UNIV_HOTBACKUP */
 
103
 
 
104
/**************************************************************//**
 
105
Gets the index id field of a page.
 
106
@return index id */
 
107
UNIV_INLINE
 
108
dulint
 
109
btr_page_get_index_id(
 
110
/*==================*/
 
111
        const page_t*   page)   /*!< in: index page */
 
112
{
 
113
        return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
 
114
}
 
115
 
 
116
#ifndef UNIV_HOTBACKUP
 
117
/********************************************************//**
 
118
Gets the node level field in an index page.
 
119
@return level, leaf level == 0 */
 
120
UNIV_INLINE
 
121
ulint
 
122
btr_page_get_level_low(
 
123
/*===================*/
 
124
        const page_t*   page)   /*!< in: index page */
 
125
{
 
126
        ulint   level;
 
127
 
 
128
        ut_ad(page);
 
129
 
 
130
        level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
 
131
 
 
132
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
133
 
 
134
        return(level);
 
135
}
 
136
 
 
137
/********************************************************//**
 
138
Gets the node level field in an index page.
 
139
@return level, leaf level == 0 */
 
140
UNIV_INLINE
 
141
ulint
 
142
btr_page_get_level(
 
143
/*===============*/
 
144
        const page_t*   page,   /*!< in: index page */
 
145
        mtr_t*          mtr __attribute__((unused)))
 
146
                                /*!< in: mini-transaction handle */
 
147
{
 
148
        ut_ad(page && mtr);
 
149
 
 
150
        return(btr_page_get_level_low(page));
 
151
}
 
152
 
 
153
/********************************************************//**
 
154
Sets the node level field in an index page. */
 
155
UNIV_INLINE
 
156
void
 
157
btr_page_set_level(
 
158
/*===============*/
 
159
        page_t*         page,   /*!< in: index page */
 
160
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
161
                                part will be updated, or NULL */
 
162
        ulint           level,  /*!< in: level, leaf level == 0 */
 
163
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
164
{
 
165
        ut_ad(page && mtr);
 
166
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
167
 
 
168
        if (UNIV_LIKELY_NULL(page_zip)) {
 
169
                mach_write_to_2(page + (PAGE_HEADER + PAGE_LEVEL), level);
 
170
                page_zip_write_header(page_zip,
 
171
                                      page + (PAGE_HEADER + PAGE_LEVEL),
 
172
                                      2, mtr);
 
173
        } else {
 
174
                mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level,
 
175
                                 MLOG_2BYTES, mtr);
 
176
        }
 
177
}
 
178
 
 
179
/********************************************************//**
 
180
Gets the next index page number.
 
181
@return next page number */
 
182
UNIV_INLINE
 
183
ulint
 
184
btr_page_get_next(
 
185
/*==============*/
 
186
        const page_t*   page,   /*!< in: index page */
 
187
        mtr_t*          mtr __attribute__((unused)))
 
188
                                /*!< in: mini-transaction handle */
 
189
{
 
190
        ut_ad(page && mtr);
 
191
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
 
192
              || mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_S_FIX));
 
193
 
 
194
        return(mach_read_from_4(page + FIL_PAGE_NEXT));
 
195
}
 
196
 
 
197
/********************************************************//**
 
198
Sets the next index page field. */
 
199
UNIV_INLINE
 
200
void
 
201
btr_page_set_next(
 
202
/*==============*/
 
203
        page_t*         page,   /*!< in: index page */
 
204
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
205
                                part will be updated, or NULL */
 
206
        ulint           next,   /*!< in: next page number */
 
207
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
208
{
 
209
        ut_ad(page && mtr);
 
210
 
 
211
        if (UNIV_LIKELY_NULL(page_zip)) {
 
212
                mach_write_to_4(page + FIL_PAGE_NEXT, next);
 
213
                page_zip_write_header(page_zip, page + FIL_PAGE_NEXT, 4, mtr);
 
214
        } else {
 
215
                mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
 
216
        }
 
217
}
 
218
 
 
219
/********************************************************//**
 
220
Gets the previous index page number.
 
221
@return prev page number */
 
222
UNIV_INLINE
 
223
ulint
 
224
btr_page_get_prev(
 
225
/*==============*/
 
226
        const page_t*   page,   /*!< in: index page */
 
227
        mtr_t*  mtr __attribute__((unused))) /*!< in: mini-transaction handle */
 
228
{
 
229
        ut_ad(page && mtr);
 
230
 
 
231
        return(mach_read_from_4(page + FIL_PAGE_PREV));
 
232
}
 
233
 
 
234
/********************************************************//**
 
235
Sets the previous index page field. */
 
236
UNIV_INLINE
 
237
void
 
238
btr_page_set_prev(
 
239
/*==============*/
 
240
        page_t*         page,   /*!< in: index page */
 
241
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
 
242
                                part will be updated, or NULL */
 
243
        ulint           prev,   /*!< in: previous page number */
 
244
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
 
245
{
 
246
        ut_ad(page && mtr);
 
247
 
 
248
        if (UNIV_LIKELY_NULL(page_zip)) {
 
249
                mach_write_to_4(page + FIL_PAGE_PREV, prev);
 
250
                page_zip_write_header(page_zip, page + FIL_PAGE_PREV, 4, mtr);
 
251
        } else {
 
252
                mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
 
253
        }
 
254
}
 
255
 
 
256
/**************************************************************//**
 
257
Gets the child node file address in a node pointer.
 
258
@return child node address */
 
259
UNIV_INLINE
 
260
ulint
 
261
btr_node_ptr_get_child_page_no(
 
262
/*===========================*/
 
263
        const rec_t*    rec,    /*!< in: node pointer record */
 
264
        const ulint*    offsets)/*!< in: array returned by rec_get_offsets() */
 
265
{
 
266
        const byte*     field;
 
267
        ulint           len;
 
268
        ulint           page_no;
 
269
 
 
270
        ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
 
271
 
 
272
        /* The child address is in the last field */
 
273
        field = rec_get_nth_field(rec, offsets,
 
274
                                  rec_offs_n_fields(offsets) - 1, &len);
 
275
 
 
276
        ut_ad(len == 4);
 
277
 
 
278
        page_no = mach_read_from_4(field);
 
279
 
 
280
        if (UNIV_UNLIKELY(page_no == 0)) {
 
281
                fprintf(stderr,
 
282
                        "InnoDB: a nonsensical page number 0"
 
283
                        " in a node ptr record at offset %lu\n",
 
284
                        (ulong) page_offset(rec));
 
285
                buf_page_print(page_align(rec), 0);
 
286
        }
 
287
 
 
288
        return(page_no);
 
289
}
 
290
 
 
291
/**************************************************************//**
 
292
Releases the latches on a leaf page and bufferunfixes it. */
 
293
UNIV_INLINE
 
294
void
 
295
btr_leaf_page_release(
 
296
/*==================*/
 
297
        buf_block_t*    block,          /*!< in: buffer block */
 
298
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF or
 
299
                                        BTR_MODIFY_LEAF */
 
300
        mtr_t*          mtr)            /*!< in: mtr */
 
301
{
 
302
        ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
 
303
        ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
 
304
 
 
305
        mtr_memo_release(mtr, block,
 
306
                         latch_mode == BTR_SEARCH_LEAF
 
307
                         ? MTR_MEMO_PAGE_S_FIX
 
308
                         : MTR_MEMO_PAGE_X_FIX);
 
309
}
 
310
#endif /* !UNIV_HOTBACKUP */