diff options
Diffstat (limited to 'storage/xtradb/include/page0cur.ic')
-rw-r--r-- | storage/xtradb/include/page0cur.ic | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/storage/xtradb/include/page0cur.ic b/storage/xtradb/include/page0cur.ic new file mode 100644 index 00000000000..9cf10ea5e3f --- /dev/null +++ b/storage/xtradb/include/page0cur.ic @@ -0,0 +1,300 @@ +/***************************************************************************** + +Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/************************************************************************ +The page cursor + +Created 10/4/1994 Heikki Tuuri +*************************************************************************/ + +#include "page0page.h" +#include "buf0types.h" + +#ifdef UNIV_DEBUG +/************************************************************* +Gets pointer to the page frame where the cursor is positioned. */ +UNIV_INLINE +page_t* +page_cur_get_page( +/*==============*/ + /* out: page */ + page_cur_t* cur) /* in: page cursor */ +{ + ut_ad(cur); + ut_ad(page_align(cur->rec) == cur->block->frame); + + return(page_align(cur->rec)); +} + +/************************************************************* +Gets pointer to the buffer block where the cursor is positioned. */ +UNIV_INLINE +buf_block_t* +page_cur_get_block( +/*===============*/ + /* out: page */ + page_cur_t* cur) /* in: page cursor */ +{ + ut_ad(cur); + ut_ad(page_align(cur->rec) == cur->block->frame); + return(cur->block); +} + +/************************************************************* +Gets pointer to the page frame where the cursor is positioned. */ +UNIV_INLINE +page_zip_des_t* +page_cur_get_page_zip( +/*==================*/ + /* out: page */ + page_cur_t* cur) /* in: page cursor */ +{ + return(buf_block_get_page_zip(page_cur_get_block(cur))); +} + +/************************************************************* +Gets the record where the cursor is positioned. */ +UNIV_INLINE +rec_t* +page_cur_get_rec( +/*=============*/ + /* out: record */ + page_cur_t* cur) /* in: page cursor */ +{ + ut_ad(cur); + ut_ad(page_align(cur->rec) == cur->block->frame); + + return(cur->rec); +} +#endif /* UNIV_DEBUG */ + +/************************************************************* +Sets the cursor object to point before the first user record +on the page. */ +UNIV_INLINE +void +page_cur_set_before_first( +/*======================*/ + const buf_block_t* block, /* in: index page */ + page_cur_t* cur) /* in: cursor */ +{ + cur->block = (buf_block_t*) block; + cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block)); +} + +/************************************************************* +Sets the cursor object to point after the last user record on +the page. */ +UNIV_INLINE +void +page_cur_set_after_last( +/*====================*/ + const buf_block_t* block, /* in: index page */ + page_cur_t* cur) /* in: cursor */ +{ + cur->block = (buf_block_t*) block; + cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block)); +} + +/************************************************************* +Returns TRUE if the cursor is before first user record on page. */ +UNIV_INLINE +ibool +page_cur_is_before_first( +/*=====================*/ + /* out: TRUE if at start */ + const page_cur_t* cur) /* in: cursor */ +{ + ut_ad(cur); + ut_ad(page_align(cur->rec) == cur->block->frame); + return(page_rec_is_infimum(cur->rec)); +} + +/************************************************************* +Returns TRUE if the cursor is after last user record. */ +UNIV_INLINE +ibool +page_cur_is_after_last( +/*===================*/ + /* out: TRUE if at end */ + const page_cur_t* cur) /* in: cursor */ +{ + ut_ad(cur); + ut_ad(page_align(cur->rec) == cur->block->frame); + return(page_rec_is_supremum(cur->rec)); +} + +/************************************************************** +Positions the cursor on the given record. */ +UNIV_INLINE +void +page_cur_position( +/*==============*/ + const rec_t* rec, /* in: record on a page */ + const buf_block_t* block, /* in: buffer block containing + the record */ + page_cur_t* cur) /* out: page cursor */ +{ + ut_ad(rec && block && cur); + ut_ad(page_align(rec) == block->frame); + + cur->rec = (rec_t*) rec; + cur->block = (buf_block_t*) block; +} + +/************************************************************** +Invalidates a page cursor by setting the record pointer NULL. */ +UNIV_INLINE +void +page_cur_invalidate( +/*================*/ + page_cur_t* cur) /* out: page cursor */ +{ + ut_ad(cur); + + cur->rec = NULL; + cur->block = NULL; +} + +/************************************************************** +Moves the cursor to the next record on page. */ +UNIV_INLINE +void +page_cur_move_to_next( +/*==================*/ + page_cur_t* cur) /* in/out: cursor; must not be after last */ +{ + ut_ad(!page_cur_is_after_last(cur)); + + cur->rec = page_rec_get_next(cur->rec); +} + +/************************************************************** +Moves the cursor to the previous record on page. */ +UNIV_INLINE +void +page_cur_move_to_prev( +/*==================*/ + page_cur_t* cur) /* in/out: page cursor, not before first */ +{ + ut_ad(!page_cur_is_before_first(cur)); + + cur->rec = page_rec_get_prev(cur->rec); +} + +/******************************************************************** +Searches the right position for a page cursor. */ +UNIV_INLINE +ulint +page_cur_search( +/*============*/ + /* out: number of matched + fields on the left */ + const buf_block_t* block, /* in: buffer block */ + const dict_index_t* index, /* in: record descriptor */ + const dtuple_t* tuple, /* in: data tuple */ + ulint mode, /* in: PAGE_CUR_L, + PAGE_CUR_LE, PAGE_CUR_G, or + PAGE_CUR_GE */ + page_cur_t* cursor) /* out: page cursor */ +{ + ulint low_matched_fields = 0; + ulint low_matched_bytes = 0; + ulint up_matched_fields = 0; + ulint up_matched_bytes = 0; + + ut_ad(dtuple_check_typed(tuple)); + + page_cur_search_with_match(block, index, tuple, mode, + &up_matched_fields, + &up_matched_bytes, + &low_matched_fields, + &low_matched_bytes, + cursor); + return(low_matched_fields); +} + +/*************************************************************** +Inserts a record next to page cursor. Returns pointer to inserted record if +succeed, i.e., enough space available, NULL otherwise. The cursor stays at +the same logical position, but the physical position may change if it is +pointing to a compressed page that was reorganized. */ +UNIV_INLINE +rec_t* +page_cur_tuple_insert( +/*==================*/ + /* out: pointer to record if succeed, NULL + otherwise */ + page_cur_t* cursor, /* in/out: a page cursor */ + const dtuple_t* tuple, /* in: pointer to a data tuple */ + dict_index_t* index, /* in: record descriptor */ + ulint n_ext, /* in: number of externally stored columns */ + mtr_t* mtr) /* in: mini-transaction handle, or NULL */ +{ + mem_heap_t* heap; + ulint* offsets; + ulint size + = rec_get_converted_size(index, tuple, n_ext); + rec_t* rec; + + heap = mem_heap_create(size + + (4 + REC_OFFS_HEADER_SIZE + + dtuple_get_n_fields(tuple)) + * sizeof *offsets); + rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(heap, size), + index, tuple, n_ext); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); + + if (buf_block_get_page_zip(cursor->block)) { + rec = page_cur_insert_rec_zip(&cursor->rec, cursor->block, + index, rec, offsets, mtr); + } else { + rec = page_cur_insert_rec_low(cursor->rec, + index, rec, offsets, mtr); + } + + mem_heap_free(heap); + return(rec); +} + +/*************************************************************** +Inserts a record next to page cursor. Returns pointer to inserted record if +succeed, i.e., enough space available, NULL otherwise. The cursor stays at +the same logical position, but the physical position may change if it is +pointing to a compressed page that was reorganized. */ +UNIV_INLINE +rec_t* +page_cur_rec_insert( +/*================*/ + /* out: pointer to record if succeed, NULL + otherwise */ + page_cur_t* cursor, /* in/out: a page cursor */ + const rec_t* rec, /* in: record to insert */ + dict_index_t* index, /* in: record descriptor */ + ulint* offsets,/* in/out: rec_get_offsets(rec, index) */ + mtr_t* mtr) /* in: mini-transaction handle, or NULL */ +{ + if (buf_block_get_page_zip(cursor->block)) { + return(page_cur_insert_rec_zip(&cursor->rec, cursor->block, + index, rec, offsets, mtr)); + } else { + return(page_cur_insert_rec_low(cursor->rec, + index, rec, offsets, mtr)); + } +} + |