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

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/include/page0cur.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/page0cur.ic
 
21
The page cursor
 
22
 
 
23
Created 10/4/1994 Heikki Tuuri
 
24
*************************************************************************/
 
25
 
 
26
#include "page0page.h"
 
27
#include "buf0types.h"
 
28
 
 
29
#ifdef UNIV_DEBUG
 
30
/*********************************************************//**
 
31
Gets pointer to the page frame where the cursor is positioned.
 
32
@return page */
 
33
UNIV_INLINE
 
34
page_t*
 
35
page_cur_get_page(
 
36
/*==============*/
 
37
        page_cur_t*     cur)    /*!< in: page cursor */
 
38
{
 
39
        ut_ad(cur);
 
40
        ut_ad(page_align(cur->rec) == cur->block->frame);
 
41
 
 
42
        return(page_align(cur->rec));
 
43
}
 
44
 
 
45
/*********************************************************//**
 
46
Gets pointer to the buffer block where the cursor is positioned.
 
47
@return page */
 
48
UNIV_INLINE
 
49
buf_block_t*
 
50
page_cur_get_block(
 
51
/*===============*/
 
52
        page_cur_t*     cur)    /*!< in: page cursor */
 
53
{
 
54
        ut_ad(cur);
 
55
        ut_ad(page_align(cur->rec) == cur->block->frame);
 
56
        return(cur->block);
 
57
}
 
58
 
 
59
/*********************************************************//**
 
60
Gets pointer to the page frame where the cursor is positioned.
 
61
@return page */
 
62
UNIV_INLINE
 
63
page_zip_des_t*
 
64
page_cur_get_page_zip(
 
65
/*==================*/
 
66
        page_cur_t*     cur)    /*!< in: page cursor */
 
67
{
 
68
        return(buf_block_get_page_zip(page_cur_get_block(cur)));
 
69
}
 
70
 
 
71
/*********************************************************//**
 
72
Gets the record where the cursor is positioned.
 
73
@return record */
 
74
UNIV_INLINE
 
75
rec_t*
 
76
page_cur_get_rec(
 
77
/*=============*/
 
78
        page_cur_t*     cur)    /*!< in: page cursor */
 
79
{
 
80
        ut_ad(cur);
 
81
        ut_ad(page_align(cur->rec) == cur->block->frame);
 
82
 
 
83
        return(cur->rec);
 
84
}
 
85
#endif /* UNIV_DEBUG */
 
86
 
 
87
/*********************************************************//**
 
88
Sets the cursor object to point before the first user record
 
89
on the page. */
 
90
UNIV_INLINE
 
91
void
 
92
page_cur_set_before_first(
 
93
/*======================*/
 
94
        const buf_block_t*      block,  /*!< in: index page */
 
95
        page_cur_t*             cur)    /*!< in: cursor */
 
96
{
 
97
        cur->block = (buf_block_t*) block;
 
98
        cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block));
 
99
}
 
100
 
 
101
/*********************************************************//**
 
102
Sets the cursor object to point after the last user record on
 
103
the page. */
 
104
UNIV_INLINE
 
105
void
 
106
page_cur_set_after_last(
 
107
/*====================*/
 
108
        const buf_block_t*      block,  /*!< in: index page */
 
109
        page_cur_t*             cur)    /*!< in: cursor */
 
110
{
 
111
        cur->block = (buf_block_t*) block;
 
112
        cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block));
 
113
}
 
114
 
 
115
/*********************************************************//**
 
116
Returns TRUE if the cursor is before first user record on page.
 
117
@return TRUE if at start */
 
118
UNIV_INLINE
 
119
ibool
 
120
page_cur_is_before_first(
 
121
/*=====================*/
 
122
        const page_cur_t*       cur)    /*!< in: cursor */
 
123
{
 
124
        ut_ad(cur);
 
125
        ut_ad(page_align(cur->rec) == cur->block->frame);
 
126
        return(page_rec_is_infimum(cur->rec));
 
127
}
 
128
 
 
129
/*********************************************************//**
 
130
Returns TRUE if the cursor is after last user record.
 
131
@return TRUE if at end */
 
132
UNIV_INLINE
 
133
ibool
 
134
page_cur_is_after_last(
 
135
/*===================*/
 
136
        const page_cur_t*       cur)    /*!< in: cursor */
 
137
{
 
138
        ut_ad(cur);
 
139
        ut_ad(page_align(cur->rec) == cur->block->frame);
 
140
        return(page_rec_is_supremum(cur->rec));
 
141
}
 
142
 
 
143
/**********************************************************//**
 
144
Positions the cursor on the given record. */
 
145
UNIV_INLINE
 
146
void
 
147
page_cur_position(
 
148
/*==============*/
 
149
        const rec_t*            rec,    /*!< in: record on a page */
 
150
        const buf_block_t*      block,  /*!< in: buffer block containing
 
151
                                        the record */
 
152
        page_cur_t*             cur)    /*!< out: page cursor */
 
153
{
 
154
        ut_ad(rec && block && cur);
 
155
        ut_ad(page_align(rec) == block->frame);
 
156
 
 
157
        cur->rec = (rec_t*) rec;
 
158
        cur->block = (buf_block_t*) block;
 
159
}
 
160
 
 
161
/**********************************************************//**
 
162
Invalidates a page cursor by setting the record pointer NULL. */
 
163
UNIV_INLINE
 
164
void
 
165
page_cur_invalidate(
 
166
/*================*/
 
167
        page_cur_t*     cur)    /*!< out: page cursor */
 
168
{
 
169
        ut_ad(cur);
 
170
 
 
171
        cur->rec = NULL;
 
172
        cur->block = NULL;
 
173
}
 
174
 
 
175
/**********************************************************//**
 
176
Moves the cursor to the next record on page. */
 
177
UNIV_INLINE
 
178
void
 
179
page_cur_move_to_next(
 
180
/*==================*/
 
181
        page_cur_t*     cur)    /*!< in/out: cursor; must not be after last */
 
182
{
 
183
        ut_ad(!page_cur_is_after_last(cur));
 
184
 
 
185
        cur->rec = page_rec_get_next(cur->rec);
 
186
}
 
187
 
 
188
/**********************************************************//**
 
189
Moves the cursor to the previous record on page. */
 
190
UNIV_INLINE
 
191
void
 
192
page_cur_move_to_prev(
 
193
/*==================*/
 
194
        page_cur_t*     cur)    /*!< in/out: page cursor, not before first */
 
195
{
 
196
        ut_ad(!page_cur_is_before_first(cur));
 
197
 
 
198
        cur->rec = page_rec_get_prev(cur->rec);
 
199
}
 
200
 
 
201
#ifndef UNIV_HOTBACKUP
 
202
/****************************************************************//**
 
203
Searches the right position for a page cursor.
 
204
@return number of matched fields on the left */
 
205
UNIV_INLINE
 
206
ulint
 
207
page_cur_search(
 
208
/*============*/
 
209
        const buf_block_t*      block,  /*!< in: buffer block */
 
210
        const dict_index_t*     index,  /*!< in: record descriptor */
 
211
        const dtuple_t*         tuple,  /*!< in: data tuple */
 
212
        ulint                   mode,   /*!< in: PAGE_CUR_L,
 
213
                                        PAGE_CUR_LE, PAGE_CUR_G, or
 
214
                                        PAGE_CUR_GE */
 
215
        page_cur_t*             cursor) /*!< out: page cursor */
 
216
{
 
217
        ulint           low_matched_fields = 0;
 
218
        ulint           low_matched_bytes = 0;
 
219
        ulint           up_matched_fields = 0;
 
220
        ulint           up_matched_bytes = 0;
 
221
 
 
222
        ut_ad(dtuple_check_typed(tuple));
 
223
 
 
224
        page_cur_search_with_match(block, index, tuple, mode,
 
225
                                   &up_matched_fields,
 
226
                                   &up_matched_bytes,
 
227
                                   &low_matched_fields,
 
228
                                   &low_matched_bytes,
 
229
                                   cursor);
 
230
        return(low_matched_fields);
 
231
}
 
232
 
 
233
/***********************************************************//**
 
234
Inserts a record next to page cursor. Returns pointer to inserted record if
 
235
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
 
236
the same logical position, but the physical position may change if it is
 
237
pointing to a compressed page that was reorganized.
 
238
@return pointer to record if succeed, NULL otherwise */
 
239
UNIV_INLINE
 
240
rec_t*
 
241
page_cur_tuple_insert(
 
242
/*==================*/
 
243
        page_cur_t*     cursor, /*!< in/out: a page cursor */
 
244
        const dtuple_t* tuple,  /*!< in: pointer to a data tuple */
 
245
        dict_index_t*   index,  /*!< in: record descriptor */
 
246
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
247
        mtr_t*          mtr)    /*!< in: mini-transaction handle, or NULL */
 
248
{
 
249
        mem_heap_t*     heap;
 
250
        ulint*          offsets;
 
251
        ulint           size
 
252
                = rec_get_converted_size(index, tuple, n_ext);
 
253
        rec_t*          rec;
 
254
 
 
255
        heap = mem_heap_create(size
 
256
                               + (4 + REC_OFFS_HEADER_SIZE
 
257
                                  + dtuple_get_n_fields(tuple))
 
258
                               * sizeof *offsets);
 
259
        rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(heap, size),
 
260
                                        index, tuple, n_ext);
 
261
        offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
262
 
 
263
        if (buf_block_get_page_zip(cursor->block)) {
 
264
                rec = page_cur_insert_rec_zip(&cursor->rec, cursor->block,
 
265
                                              index, rec, offsets, mtr);
 
266
        } else {
 
267
                rec = page_cur_insert_rec_low(cursor->rec,
 
268
                                              index, rec, offsets, mtr);
 
269
        }
 
270
 
 
271
        mem_heap_free(heap);
 
272
        return(rec);
 
273
}
 
274
#endif /* !UNIV_HOTBACKUP */
 
275
 
 
276
/***********************************************************//**
 
277
Inserts a record next to page cursor. Returns pointer to inserted record if
 
278
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
 
279
the same logical position, but the physical position may change if it is
 
280
pointing to a compressed page that was reorganized.
 
281
@return pointer to record if succeed, NULL otherwise */
 
282
UNIV_INLINE
 
283
rec_t*
 
284
page_cur_rec_insert(
 
285
/*================*/
 
286
        page_cur_t*     cursor, /*!< in/out: a page cursor */
 
287
        const rec_t*    rec,    /*!< in: record to insert */
 
288
        dict_index_t*   index,  /*!< in: record descriptor */
 
289
        ulint*          offsets,/*!< in/out: rec_get_offsets(rec, index) */
 
290
        mtr_t*          mtr)    /*!< in: mini-transaction handle, or NULL */
 
291
{
 
292
        if (buf_block_get_page_zip(cursor->block)) {
 
293
                return(page_cur_insert_rec_zip(&cursor->rec, cursor->block,
 
294
                                               index, rec, offsets, mtr));
 
295
        } else {
 
296
                return(page_cur_insert_rec_low(cursor->rec,
 
297
                                               index, rec, offsets, mtr));
 
298
        }
 
299
}