~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/******************************************************
2
The B-tree
3
4
(c) 1994-1996 Innobase Oy
5
6
Created 6/2/1994 Heikki Tuuri
7
*******************************************************/
8
9
#include "mach0data.h"
10
#include "mtr0mtr.h"
11
#include "mtr0log.h"
12
13
#define BTR_MAX_NODE_LEVEL	50	/* used in debug checking */
14
15
/******************************************************************
16
Gets a buffer page and declares its latching order level. */
17
UNIV_INLINE
18
page_t*
19
btr_page_get(
20
/*=========*/
21
	ulint	space,		/* in: space id */
22
	ulint	page_no,	/* in: page number */
23
	ulint	mode,		/* in: latch mode */
24
	mtr_t*	mtr)		/* in: mtr */
25
{
26
	page_t*	page;
27
28
	page = buf_page_get(space, page_no, mode, mtr);
29
#ifdef UNIV_SYNC_DEBUG
30
	if (mode != RW_NO_LATCH) {
31
32
		buf_page_dbg_add_level(page, SYNC_TREE_NODE);
33
	}
34
#endif
35
	return(page);
36
}
37
38
/******************************************************************
39
Sets the index id field of a page. */
40
UNIV_INLINE
41
void
42
btr_page_set_index_id(
43
/*==================*/
44
	page_t*		page,	/* in: page to be created */
45
	dulint		id,	/* in: index id */
46
	mtr_t*		mtr)	/* in: mtr */
47
{
48
	mlog_write_dulint(page + PAGE_HEADER + PAGE_INDEX_ID, id, mtr);
49
}
50
51
/******************************************************************
52
Gets the index id field of a page. */
53
UNIV_INLINE
54
dulint
55
btr_page_get_index_id(
56
/*==================*/
57
				/* out: index id */
58
	page_t*		page)	/* in: index page */
59
{
60
	return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
61
}
62
63
/************************************************************
64
Gets the node level field in an index page. */
65
UNIV_INLINE
66
ulint
67
btr_page_get_level_low(
68
/*===================*/
69
			/* out: level, leaf level == 0 */
70
	page_t*	page)	/* in: index page */
71
{
72
	ulint	level;
73
74
	ut_ad(page);
75
76
	level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
77
78
	ut_ad(level <= BTR_MAX_NODE_LEVEL);
79
80
	return(level);
81
}
82
83
/************************************************************
84
Gets the node level field in an index page. */
85
UNIV_INLINE
86
ulint
87
btr_page_get_level(
88
/*===============*/
89
			/* out: level, leaf level == 0 */
90
	page_t*	page,	/* in: index page */
91
	mtr_t*	mtr __attribute__((unused))) /* in: mini-transaction handle */
92
{
93
	ut_ad(page && mtr);
94
95
	return(btr_page_get_level_low(page));
96
}
97
98
/************************************************************
99
Sets the node level field in an index page. */
100
UNIV_INLINE
101
void
102
btr_page_set_level(
103
/*===============*/
104
	page_t*	page,	/* in: index page */
105
	ulint	level,	/* in: level, leaf level == 0 */
106
	mtr_t*	mtr)	/* in: mini-transaction handle */
107
{
108
	ut_ad(page && mtr);
109
	ut_ad(level <= BTR_MAX_NODE_LEVEL);
110
111
	mlog_write_ulint(page + PAGE_HEADER + PAGE_LEVEL, level,
112
			 MLOG_2BYTES, mtr);
113
}
114
115
/************************************************************
116
Gets the next index page number. */
117
UNIV_INLINE
118
ulint
119
btr_page_get_next(
120
/*==============*/
121
			/* out: next page number */
122
	page_t*	page,	/* in: index page */
123
	mtr_t*	mtr __attribute__((unused))) /* in: mini-transaction handle */
124
{
125
	ut_ad(page && mtr);
126
	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
127
				MTR_MEMO_PAGE_X_FIX)
128
	      || mtr_memo_contains(mtr, buf_block_align(page),
129
				   MTR_MEMO_PAGE_S_FIX));
130
131
	return(mach_read_from_4(page + FIL_PAGE_NEXT));
132
}
133
134
/************************************************************
135
Sets the next index page field. */
136
UNIV_INLINE
137
void
138
btr_page_set_next(
139
/*==============*/
140
	page_t*	page,	/* in: index page */
141
	ulint	next,	/* in: next page number */
142
	mtr_t*	mtr)	/* in: mini-transaction handle */
143
{
144
	ut_ad(page && mtr);
145
146
	mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
147
}
148
149
/************************************************************
150
Gets the previous index page number. */
151
UNIV_INLINE
152
ulint
153
btr_page_get_prev(
154
/*==============*/
155
			/* out: prev page number */
156
	page_t*	page,	/* in: index page */
157
	mtr_t*	mtr __attribute__((unused))) /* in: mini-transaction handle */
158
{
159
	ut_ad(page && mtr);
160
161
	return(mach_read_from_4(page + FIL_PAGE_PREV));
162
}
163
164
/************************************************************
165
Sets the previous index page field. */
166
UNIV_INLINE
167
void
168
btr_page_set_prev(
169
/*==============*/
170
	page_t*	page,	/* in: index page */
171
	ulint	prev,	/* in: previous page number */
172
	mtr_t*	mtr)	/* in: mini-transaction handle */
173
{
174
	ut_ad(page && mtr);
175
176
	mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
177
}
178
179
/******************************************************************
180
Gets the child node file address in a node pointer. */
181
UNIV_INLINE
182
ulint
183
btr_node_ptr_get_child_page_no(
184
/*===========================*/
185
				/* out: child node address */
186
	rec_t*		rec,	/* in: node pointer record */
187
	const ulint*	offsets)/* in: array returned by rec_get_offsets() */
188
{
189
	byte*	field;
190
	ulint	len;
191
	ulint	page_no;
192
193
	ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
194
195
	/* The child address is in the last field */
196
	field = rec_get_nth_field(rec, offsets,
197
				  rec_offs_n_fields(offsets) - 1, &len);
198
199
	ut_ad(len == 4);
200
201
	page_no = mach_read_from_4(field);
202
203
	if (UNIV_UNLIKELY(page_no == 0)) {
204
		fprintf(stderr,
205
			"InnoDB: a nonsensical page number 0"
206
			" in a node ptr record at offset %lu\n",
207
			(ulong) page_offset(rec));
208
		buf_page_print(buf_frame_align(rec));
209
	}
210
211
	return(page_no);
212
}
213
214
/******************************************************************
215
Releases the latches on a leaf page and bufferunfixes it. */
216
UNIV_INLINE
217
void
218
btr_leaf_page_release(
219
/*==================*/
220
	page_t*	page,		/* in: page */
221
	ulint	latch_mode,	/* in: BTR_SEARCH_LEAF or BTR_MODIFY_LEAF */
222
	mtr_t*	mtr)		/* in: mtr */
223
{
224
	ut_ad(!mtr_memo_contains(mtr, buf_block_align(page),
225
				 MTR_MEMO_MODIFY));
226
	if (latch_mode == BTR_SEARCH_LEAF) {
227
		mtr_memo_release(mtr, buf_block_align(page),
228
				 MTR_MEMO_PAGE_S_FIX);
229
	} else {
230
		ut_ad(latch_mode == BTR_MODIFY_LEAF);
231
		mtr_memo_release(mtr, buf_block_align(page),
232
				 MTR_MEMO_PAGE_X_FIX);
233
	}
234
}