/***************************************************************************** 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 index tree cursor Created 10/16/1994 Heikki Tuuri *******************************************************/ #include "btr0btr.h" #ifdef UNIV_DEBUG /************************************************************* Returns the page cursor component of a tree cursor. */ UNIV_INLINE page_cur_t* btr_cur_get_page_cur( /*=================*/ /* out: pointer to page cursor component */ const btr_cur_t* cursor) /* in: tree cursor */ { return(&((btr_cur_t*) cursor)->page_cur); } #endif /* UNIV_DEBUG */ /************************************************************* Returns the buffer block on which the tree cursor is positioned. */ UNIV_INLINE buf_block_t* btr_cur_get_block( /*==============*/ /* out: pointer to buffer block */ btr_cur_t* cursor) /* in: tree cursor */ { return(page_cur_get_block(btr_cur_get_page_cur(cursor))); } /************************************************************* Returns the record pointer of a tree cursor. */ UNIV_INLINE rec_t* btr_cur_get_rec( /*============*/ /* out: pointer to record */ btr_cur_t* cursor) /* in: tree cursor */ { return(page_cur_get_rec(&(cursor->page_cur))); } /************************************************************* Returns the compressed page on which the tree cursor is positioned. */ UNIV_INLINE page_zip_des_t* btr_cur_get_page_zip( /*=================*/ /* out: pointer to compressed page, or NULL if the page is not compressed */ btr_cur_t* cursor) /* in: tree cursor */ { return(buf_block_get_page_zip(btr_cur_get_block(cursor))); } /************************************************************* Invalidates a tree cursor by setting record pointer to NULL. */ UNIV_INLINE void btr_cur_invalidate( /*===============*/ btr_cur_t* cursor) /* in: tree cursor */ { page_cur_invalidate(&(cursor->page_cur)); } /************************************************************* Returns the page of a tree cursor. */ UNIV_INLINE page_t* btr_cur_get_page( /*=============*/ /* out: pointer to page */ btr_cur_t* cursor) /* in: tree cursor */ { return(page_align(page_cur_get_rec(&(cursor->page_cur)))); } /************************************************************* Returns the index of a cursor. */ UNIV_INLINE dict_index_t* btr_cur_get_index( /*==============*/ /* out: index */ btr_cur_t* cursor) /* in: B-tree cursor */ { return(cursor->index); } /************************************************************* Positions a tree cursor at a given record. */ UNIV_INLINE void btr_cur_position( /*=============*/ dict_index_t* index, /* in: index */ rec_t* rec, /* in: record in tree */ buf_block_t* block, /* in: buffer block of rec */ btr_cur_t* cursor) /* out: cursor */ { ut_ad(page_align(rec) == block->frame); page_cur_position(rec, block, btr_cur_get_page_cur(cursor)); cursor->index = index; } /************************************************************************* Checks if compressing an index page where a btr cursor is placed makes sense. */ UNIV_INLINE ibool btr_cur_compress_recommendation( /*============================*/ /* out: TRUE if compression is recommended */ btr_cur_t* cursor, /* in: btr cursor */ mtr_t* mtr) /* in: mtr */ { page_t* page; ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX)); page = btr_cur_get_page(cursor); if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT) || ((btr_page_get_next(page, mtr) == FIL_NULL) && (btr_page_get_prev(page, mtr) == FIL_NULL))) { /* The page fillfactor has dropped below a predefined minimum value OR the level in the B-tree contains just one page: we recommend compression if this is not the root page. */ return(dict_index_get_page(cursor->index) != page_get_page_no(page)); } return(FALSE); } /************************************************************************* Checks if the record on which the cursor is placed can be deleted without making tree compression necessary (or, recommended). */ UNIV_INLINE ibool btr_cur_can_delete_without_compress( /*================================*/ /* out: TRUE if can be deleted without recommended compression */ btr_cur_t* cursor, /* in: btr cursor */ ulint rec_size,/* in: rec_get_size(btr_cur_get_rec(cursor))*/ mtr_t* mtr) /* in: mtr */ { page_t* page; ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX)); page = btr_cur_get_page(cursor); if ((page_get_data_size(page) - rec_size < BTR_CUR_PAGE_COMPRESS_LIMIT) || ((btr_page_get_next(page, mtr) == FIL_NULL) && (btr_page_get_prev(page, mtr) == FIL_NULL)) || (page_get_n_recs(page) < 2)) { /* The page fillfactor will drop below a predefined minimum value, OR the level in the B-tree contains just one page, OR the page will become empty: we recommend compression if this is not the root page. */ return(dict_index_get_page(cursor->index) == page_get_page_no(page)); } return(TRUE); }