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