~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-12-24 02:13:05 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101224021305-e3slv1cyjczqorij
Changed the bzrignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (C) 1994, 2010, 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., 51 Franklin
 
15
St, Fifth Floor, Boston, MA 02110-1301 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
        mtr_t*          mtr)            /*!< in/out: mtr */
 
52
{
 
53
        buf_block_t*    block;
 
54
 
 
55
        block = buf_page_get_gen(space, zip_size, page_no, mode,
 
56
                                 NULL, BUF_GET, file, line, mtr);
 
57
 
 
58
        if (mode != RW_NO_LATCH) {
 
59
 
 
60
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
61
        }
 
62
 
 
63
        return(block);
 
64
}
 
65
 
 
66
/**************************************************************//**
 
67
Sets the index id field of a page. */
 
68
UNIV_INLINE
 
69
void
 
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 */
 
77
{
 
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),
 
82
                                      8, mtr);
 
83
        } else {
 
84
                mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr);
 
85
        }
 
86
}
 
87
#endif /* !UNIV_HOTBACKUP */
 
88
 
 
89
/**************************************************************//**
 
90
Gets the index id field of a page.
 
91
@return index id */
 
92
UNIV_INLINE
 
93
index_id_t
 
94
btr_page_get_index_id(
 
95
/*==================*/
 
96
        const page_t*   page)   /*!< in: index page */
 
97
{
 
98
        return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
 
99
}
 
100
 
 
101
#ifndef UNIV_HOTBACKUP
 
102
/********************************************************//**
 
103
Gets the node level field in an index page.
 
104
@return level, leaf level == 0 */
 
105
UNIV_INLINE
 
106
ulint
 
107
btr_page_get_level_low(
 
108
/*===================*/
 
109
        const page_t*   page)   /*!< in: index page */
 
110
{
 
111
        ulint   level;
 
112
 
 
113
        ut_ad(page);
 
114
 
 
115
        level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
 
116
 
 
117
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
118
 
 
119
        return(level);
 
120
}
 
121
 
 
122
/********************************************************//**
 
123
Gets the node level field in an index page.
 
124
@return level, leaf level == 0 */
 
125
UNIV_INLINE
 
126
ulint
 
127
btr_page_get_level(
 
128
/*===============*/
 
129
        const page_t*   page,   /*!< in: index page */
 
130
        mtr_t*          mtr __attribute__((unused)))
 
131
                                /*!< in: mini-transaction handle */
 
132
{
 
133
        (void)mtr;
 
134
        ut_ad(page && mtr);
 
135
 
 
136
        return(btr_page_get_level_low(page));
 
137
}
 
138
 
 
139
/********************************************************//**
 
140
Sets the node level field in an index page. */
 
141
UNIV_INLINE
 
142
void
 
143
btr_page_set_level(
 
144
/*===============*/
 
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 */
 
150
{
 
151
        ut_ad(page && mtr);
 
152
        ut_ad(level <= BTR_MAX_NODE_LEVEL);
 
153
 
 
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),
 
158
                                      2, mtr);
 
159
        } else {
 
160
                mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level,
 
161
                                 MLOG_2BYTES, mtr);
 
162
        }
 
163
}
 
164
 
 
165
/********************************************************//**
 
166
Gets the next index page number.
 
167
@return next page number */
 
168
UNIV_INLINE
 
169
ulint
 
170
btr_page_get_next(
 
171
/*==============*/
 
172
        const page_t*   page,   /*!< in: index page */
 
173
        mtr_t*          mtr __attribute__((unused)))
 
174
                                /*!< in: mini-transaction handle */
 
175
{
 
176
        (void)mtr;
 
177
        ut_ad(page && mtr);
 
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));
 
180
 
 
181
        return(mach_read_from_4(page + FIL_PAGE_NEXT));
 
182
}
 
183
 
 
184
/********************************************************//**
 
185
Sets the next index page field. */
 
186
UNIV_INLINE
 
187
void
 
188
btr_page_set_next(
 
189
/*==============*/
 
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 */
 
195
{
 
196
        ut_ad(page && mtr);
 
197
 
 
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);
 
201
        } else {
 
202
                mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
 
203
        }
 
204
}
 
205
 
 
206
/********************************************************//**
 
207
Gets the previous index page number.
 
208
@return prev page number */
 
209
UNIV_INLINE
 
210
ulint
 
211
btr_page_get_prev(
 
212
/*==============*/
 
213
        const page_t*   page,   /*!< in: index page */
 
214
        mtr_t*  mtr __attribute__((unused))) /*!< in: mini-transaction handle */
 
215
{
 
216
        (void)mtr;
 
217
        ut_ad(page && mtr);
 
218
 
 
219
        return(mach_read_from_4(page + FIL_PAGE_PREV));
 
220
}
 
221
 
 
222
/********************************************************//**
 
223
Sets the previous index page field. */
 
224
UNIV_INLINE
 
225
void
 
226
btr_page_set_prev(
 
227
/*==============*/
 
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 */
 
233
{
 
234
        ut_ad(page && mtr);
 
235
 
 
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);
 
239
        } else {
 
240
                mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
 
241
        }
 
242
}
 
243
 
 
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 */
 
251
UNIV_INLINE
 
252
ulint
 
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() */
 
257
{
 
258
        const byte*     field;
 
259
        ulint           len;
 
260
        ulint           page_no;
 
261
 
 
262
        ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
 
263
 
 
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);
 
267
 
 
268
        ut_ad(len == 4);
 
269
 
 
270
        page_no = mach_read_from_4(field);
 
271
 
 
272
        if (UNIV_UNLIKELY(page_no == 0)) {
 
273
                fprintf(stderr,
 
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);
 
278
        }
 
279
 
 
280
        return(page_no);
 
281
}
 
282
 
 
283
/**************************************************************//**
 
284
Releases the latches on a leaf page and bufferunfixes it. */
 
285
UNIV_INLINE
 
286
void
 
287
btr_leaf_page_release(
 
288
/*==================*/
 
289
        buf_block_t*    block,          /*!< in: buffer block */
 
290
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF or
 
291
                                        BTR_MODIFY_LEAF */
 
292
        mtr_t*          mtr)            /*!< in: mtr */
 
293
{
 
294
        ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
 
295
        ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
 
296
 
 
297
        mtr_memo_release(mtr, block,
 
298
                         latch_mode == BTR_SEARCH_LEAF
 
299
                         ? MTR_MEMO_PAGE_S_FIX
 
300
                         : MTR_MEMO_PAGE_X_FIX);
 
301
}
 
302
#endif /* !UNIV_HOTBACKUP */