83
84
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
84
85
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
87
block = btr_pcur_get_block(cursor);
86
88
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
88
90
page_cursor = btr_pcur_get_page_cur(cursor);
91
93
page = page_align(rec);
92
94
offs = page_offset(rec);
94
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
96
|| mtr_memo_contains(mtr, buf_block_align(page),
97
MTR_MEMO_PAGE_X_FIX));
96
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_S_FIX)
97
|| mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
98
98
ut_a(cursor->latch_mode != BTR_NO_LATCHES);
100
100
if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
137
137
index, rec, &cursor->old_n_fields,
138
138
&cursor->old_rec_buf, &cursor->buf_size);
140
cursor->block_when_stored = buf_block_align(page);
141
cursor->modify_clock = buf_block_get_modify_clock(
142
cursor->block_when_stored);
140
cursor->block_when_stored = block;
141
cursor->modify_clock = buf_block_get_modify_clock(block);
145
144
/******************************************************************
146
145
Copies the stored position of a pcur to another pcur. */
149
148
btr_pcur_copy_stored_position(
150
149
/*==========================*/
184
183
GREATER than the user record which was the predecessor of the supremum.
185
184
(4) cursor was positioned before the first or after the last in an empty tree:
186
185
restores to before first or after the last in the tree. */
189
188
btr_pcur_restore_position(
190
189
/*======================*/
221
cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
222
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
219
(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
220
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
224
222
/* In these cases we do not try an optimistic restoration,
225
223
but always do a search */
228
226
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
229
227
index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
231
cursor->block_when_stored
232
= buf_block_align(btr_pcur_get_page(cursor));
229
cursor->block_when_stored = btr_pcur_get_block(cursor);
237
234
ut_a(cursor->old_rec);
238
235
ut_a(cursor->old_n_fields);
240
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
242
237
if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
243
238
|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
244
239
/* Try optimistic restoration */
246
241
if (UNIV_LIKELY(buf_page_optimistic_get(
248
cursor->block_when_stored, page,
243
cursor->block_when_stored,
249
244
cursor->modify_clock, mtr))) {
250
245
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
251
246
#ifdef UNIV_SYNC_DEBUG
252
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
247
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
253
249
#endif /* UNIV_SYNC_DEBUG */
254
250
if (cursor->rel_pos == BTR_PCUR_ON) {
255
251
#ifdef UNIV_DEBUG
253
const ulint* offsets1;
254
const ulint* offsets2;
259
255
#endif /* UNIV_DEBUG */
260
256
cursor->latch_mode = latch_mode;
261
257
#ifdef UNIV_DEBUG
307
303
cursor->search_mode = old_mode;
309
305
if (cursor->rel_pos == BTR_PCUR_ON
310
&& btr_pcur_is_on_user_rec(cursor, mtr)
306
&& btr_pcur_is_on_user_rec(cursor)
311
307
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
313
309
btr_pcur_get_rec(cursor), index,
317
313
the cursor can now be on a different page! But we can retain
318
314
the value of old_rec */
320
cursor->block_when_stored = buf_block_align(
321
btr_pcur_get_page(cursor));
316
cursor->block_when_stored = btr_pcur_get_block(cursor);
322
317
cursor->modify_clock = buf_block_get_modify_clock(
323
318
cursor->block_when_stored);
324
319
cursor->old_stored = BTR_PCUR_OLD_STORED;
345
340
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
346
341
made by the current mini-transaction to the data protected by the
347
342
cursor latch, as then the latch must not be released until mtr_commit. */
350
345
btr_pcur_release_leaf(
351
346
/*==================*/
352
347
btr_pcur_t* cursor, /* in: persistent cursor */
353
348
mtr_t* mtr) /* in: mtr */
357
352
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
358
353
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
360
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
355
block = btr_pcur_get_block(cursor);
362
btr_leaf_page_release(page, cursor->latch_mode, mtr);
357
btr_leaf_page_release(block, cursor->latch_mode, mtr);
364
359
cursor->latch_mode = BTR_NO_LATCHES;
371
366
latch on the current page, and bufferunfixes it. Note that there must not be
372
367
modifications on the current page, as then the x-latch can be released only in
376
371
btr_pcur_move_to_next_page(
377
372
/*=======================*/
379
374
last record of the current page */
380
375
mtr_t* mtr) /* in: mtr */
381
buf_block_t* next_block;
387
384
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
388
385
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
389
ut_ad(btr_pcur_is_after_last_on_page(cursor, mtr));
386
ut_ad(btr_pcur_is_after_last_on_page(cursor));
391
388
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
393
390
page = btr_pcur_get_page(cursor);
395
391
next_page_no = btr_page_get_next(page, mtr);
396
space = buf_frame_get_space_id(page);
392
space = buf_block_get_space(btr_pcur_get_block(cursor));
393
zip_size = buf_block_get_zip_size(btr_pcur_get_block(cursor));
398
395
ut_ad(next_page_no != FIL_NULL);
400
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
397
next_block = btr_block_get(space, zip_size, next_page_no,
398
cursor->latch_mode, mtr);
399
next_page = buf_block_get_frame(next_block);
401
400
#ifdef UNIV_BTR_DEBUG
402
ut_a(btr_page_get_prev(next_page, mtr) == buf_frame_get_page_no(page));
401
ut_a(page_is_comp(next_page) == page_is_comp(page));
402
ut_a(btr_page_get_prev(next_page, mtr)
403
== buf_block_get_page_no(btr_pcur_get_block(cursor)));
403
404
#endif /* UNIV_BTR_DEBUG */
404
ut_a(page_is_comp(next_page) == page_is_comp(page));
405
buf_block_align(next_page)->check_index_page_at_flush = TRUE;
407
btr_leaf_page_release(page, cursor->latch_mode, mtr);
409
page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
405
next_block->check_index_page_at_flush = TRUE;
407
btr_leaf_page_release(btr_pcur_get_block(cursor),
408
cursor->latch_mode, mtr);
410
page_cur_set_before_first(next_block, btr_pcur_get_page_cur(cursor));
411
412
page_check_dir(next_page);
420
421
return, but it may happen that the cursor is not positioned on the last
421
422
record of any page, because the structure of the tree may have changed
422
423
during the time when the cursor had no latches. */
425
426
btr_pcur_move_backward_from_page(
426
427
/*=============================*/
428
429
record of the current page */
429
430
mtr_t* mtr) /* in: mtr */
435
buf_block_t* prev_block;
438
439
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
439
440
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
440
ut_ad(btr_pcur_is_before_first_on_page(cursor, mtr));
441
ut_ad(btr_pcur_is_before_first_on_page(cursor));
441
442
ut_ad(!btr_pcur_is_before_first_in_tree(cursor, mtr));
443
444
latch_mode = cursor->latch_mode;
465
466
page = btr_pcur_get_page(cursor);
467
468
prev_page_no = btr_page_get_prev(page, mtr);
468
space = buf_frame_get_space_id(page);
470
if (btr_pcur_is_before_first_on_page(cursor, mtr)
471
&& (prev_page_no != FIL_NULL)) {
473
prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
475
btr_leaf_page_release(page, latch_mode, mtr);
477
page_cur_set_after_last(prev_page,
469
space = buf_block_get_space(btr_pcur_get_block(cursor));
471
if (prev_page_no == FIL_NULL) {
472
} else if (btr_pcur_is_before_first_on_page(cursor)) {
474
prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
476
btr_leaf_page_release(btr_pcur_get_block(cursor),
479
page_cur_set_after_last(prev_block,
478
480
btr_pcur_get_page_cur(cursor));
479
} else if (prev_page_no != FIL_NULL) {
481
483
/* The repositioned cursor did not end on an infimum record on
482
484
a page. Cursor repositioning acquired a latch also on the
483
485
previous page, but we do not need the latch: release it. */
485
prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
487
prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
487
btr_leaf_page_release(prev_page, latch_mode, mtr);
489
btr_leaf_page_release(prev_block, latch_mode, mtr);
490
492
cursor->latch_mode = latch_mode;
511
513
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
513
if (btr_pcur_is_before_first_on_page(cursor, mtr)) {
515
if (btr_pcur_is_before_first_on_page(cursor)) {
515
517
if (btr_pcur_is_before_first_in_tree(cursor, mtr)) {
534
536
in the first case sets the cursor after last in tree, and in the latter case
535
537
before first in tree. The latching mode must be BTR_SEARCH_LEAF or
536
538
BTR_MODIFY_LEAF. */
539
541
btr_pcur_open_on_user_rec(
540
542
/*======================*/
541
543
dict_index_t* index, /* in: index */
542
dtuple_t* tuple, /* in: tuple on which search done */
544
const dtuple_t* tuple, /* in: tuple on which search done */
543
545
ulint mode, /* in: PAGE_CUR_L, ... */
544
546
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
545
547
BTR_MODIFY_LEAF */
552
554
if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
554
if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
556
if (btr_pcur_is_after_last_on_page(cursor)) {
556
558
btr_pcur_move_to_next_user_rec(cursor, mtr);