📄 btr0pcur.c
字号:
/******************************************************The index tree persistent cursor(c) 1996 Innobase OyCreated 2/23/1996 Heikki Tuuri*******************************************************/#include "btr0pcur.h"#ifdef UNIV_NONINL#include "btr0pcur.ic"#endif#include "ut0byte.h"#include "rem0cmp.h"#include "trx0trx.h"/******************************************************************Allocates memory for a persistent cursor object and initializes the cursor. */btr_pcur_t*btr_pcur_create_for_mysql(void)/*============================*/ /* out, own: persistent cursor */{ btr_pcur_t* pcur; pcur = mem_alloc(sizeof(btr_pcur_t)); pcur->btr_cur.index = NULL; btr_pcur_init(pcur); return(pcur);}/******************************************************************Frees the memory for a persistent cursor object. */voidbtr_pcur_free_for_mysql(/*====================*/ btr_pcur_t* cursor) /* in, own: persistent cursor */{ if (cursor->old_rec_buf != NULL) { mem_free(cursor->old_rec_buf); cursor->old_rec_buf = NULL; } cursor->btr_cur.page_cur.rec = NULL; cursor->old_rec = NULL; cursor->old_n_fields = 0; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->latch_mode = BTR_NO_LATCHES; cursor->pos_state = BTR_PCUR_NOT_POSITIONED; mem_free(cursor);}/******************************************************************The position of the cursor is stored by taking an initial segment of therecord the cursor is positioned on, before, or after, and copying it to thecursor data structure, or just setting a flag if the cursor id before thefirst in an EMPTY tree, or after the last in an EMPTY tree. NOTE that thepage where the cursor is positioned must not be empty if the index tree isnot totally empty! */voidbtr_pcur_store_position(/*====================*/ btr_pcur_t* cursor, /* in: persistent cursor */ mtr_t* mtr) /* in: mtr */{ page_cur_t* page_cursor; rec_t* rec; dict_tree_t* tree; page_t* page; ulint offs; ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->latch_mode != BTR_NO_LATCHES); tree = btr_cur_get_tree(btr_pcur_get_btr_cur(cursor)); page_cursor = btr_pcur_get_page_cur(cursor); rec = page_cur_get_rec(page_cursor); page = ut_align_down(rec, UNIV_PAGE_SIZE); offs = ut_align_offset(rec, UNIV_PAGE_SIZE); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_S_FIX) || mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); ut_a(cursor->latch_mode != BTR_NO_LATCHES); if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) { /* It must be an empty index tree; NOTE that in this case we do not store the modify_clock, but always do a search if we restore the cursor position */ ut_a(btr_page_get_next(page, mtr) == FIL_NULL); ut_a(btr_page_get_prev(page, mtr) == FIL_NULL); cursor->old_stored = BTR_PCUR_OLD_STORED; if (page_rec_is_supremum_low(offs)) { cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE; } else { cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE; } return; } if (page_rec_is_supremum_low(offs)) { rec = page_rec_get_prev(rec); cursor->rel_pos = BTR_PCUR_AFTER; } else if (page_rec_is_infimum_low(offs)) { rec = page_rec_get_next(rec); cursor->rel_pos = BTR_PCUR_BEFORE; } else { cursor->rel_pos = BTR_PCUR_ON; } cursor->old_stored = BTR_PCUR_OLD_STORED; cursor->old_rec = dict_tree_copy_rec_order_prefix(tree, rec, &cursor->old_n_fields, &cursor->old_rec_buf, &cursor->buf_size); cursor->block_when_stored = buf_block_align(page); cursor->modify_clock = buf_block_get_modify_clock( cursor->block_when_stored);}/******************************************************************Copies the stored position of a pcur to another pcur. */voidbtr_pcur_copy_stored_position(/*==========================*/ btr_pcur_t* pcur_receive, /* in: pcur which will receive the position info */ btr_pcur_t* pcur_donate) /* in: pcur from which the info is copied */{ if (pcur_receive->old_rec_buf) { mem_free(pcur_receive->old_rec_buf); } ut_memcpy((byte*)pcur_receive, (byte*)pcur_donate, sizeof(btr_pcur_t)); if (pcur_donate->old_rec_buf) { pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size); ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf, pcur_donate->buf_size); pcur_receive->old_rec = pcur_receive->old_rec_buf + (pcur_donate->old_rec - pcur_donate->old_rec_buf); } pcur_receive->old_n_fields = pcur_donate->old_n_fields;}/******************************************************************Restores the stored position of a persistent cursor bufferfixing the page andobtaining the specified latches. If the cursor position was saved when the(1) cursor was positioned on a user record: this function restores the positionto the last record LESS OR EQUAL to the stored record;(2) cursor was positioned on a page infimum record: restores the position tothe last record LESS than the user record which was the successor of the pageinfimum;(3) cursor was positioned on the page supremum: restores to the first recordGREATER than the user record which was the predecessor of the supremum.(4) cursor was positioned before the first or after the last in an empty tree:restores to before first or after the last in the tree. */iboolbtr_pcur_restore_position(/*======================*/ /* out: TRUE if the cursor position was stored when it was on a user record and it can be restored on a user record whose ordering fields are identical to the ones of the original user record */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ btr_pcur_t* cursor, /* in: detached persistent cursor */ mtr_t* mtr) /* in: mtr */{ dict_tree_t* tree; page_t* page; dtuple_t* tuple; ulint mode; ulint old_mode; mem_heap_t* heap; if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED) || UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED && cursor->pos_state != BTR_PCUR_IS_POSITIONED)) { ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t)); if (cursor->trx_if_known) { trx_print(stderr, cursor->trx_if_known, 0); } ut_error; } if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) { /* In these cases we do not try an optimistic restoration, but always do a search */ btr_cur_open_at_index_side( cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE, btr_pcur_get_btr_cur(cursor)->index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr); cursor->block_when_stored = buf_block_align(btr_pcur_get_page(cursor)); return(FALSE); } ut_a(cursor->old_rec); ut_a(cursor->old_n_fields); page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor)); if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF) || UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) { /* Try optimistic restoration */ if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode, cursor->block_when_stored, page, cursor->modify_clock, mtr))) { cursor->pos_state = BTR_PCUR_IS_POSITIONED;#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_TREE_NODE);#endif /* UNIV_SYNC_DEBUG */ if (cursor->rel_pos == BTR_PCUR_ON) {#ifdef UNIV_DEBUG rec_t* rec; ulint* offsets1; ulint* offsets2; dict_index_t* index;#endif /* UNIV_DEBUG */ cursor->latch_mode = latch_mode;#ifdef UNIV_DEBUG rec = btr_pcur_get_rec(cursor); index = dict_tree_find_index( btr_cur_get_tree( btr_pcur_get_btr_cur(cursor)), rec); heap = mem_heap_create(256); offsets1 = rec_get_offsets(cursor->old_rec, index, NULL, cursor->old_n_fields, &heap); offsets2 = rec_get_offsets(rec, index, NULL, cursor->old_n_fields, &heap); ut_ad(cmp_rec_rec(cursor->old_rec, rec, offsets1, offsets2, index) == 0); mem_heap_free(heap);#endif /* UNIV_DEBUG */ return(TRUE); } return(FALSE); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -