~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/btr/btr0pcur.c

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
/******************************************************************
20
20
Allocates memory for a persistent cursor object and initializes the cursor. */
21
 
UNIV_INTERN
 
21
 
22
22
btr_pcur_t*
23
23
btr_pcur_create_for_mysql(void)
24
24
/*============================*/
36
36
 
37
37
/******************************************************************
38
38
Frees the memory for a persistent cursor object. */
39
 
UNIV_INTERN
 
39
 
40
40
void
41
41
btr_pcur_free_for_mysql(
42
42
/*====================*/
67
67
first in an EMPTY tree, or after the last in an EMPTY tree. NOTE that the
68
68
page where the cursor is positioned must not be empty if the index tree is
69
69
not totally empty! */
70
 
UNIV_INTERN
 
70
 
71
71
void
72
72
btr_pcur_store_position(
73
73
/*====================*/
75
75
        mtr_t*          mtr)    /* in: mtr */
76
76
{
77
77
        page_cur_t*     page_cursor;
78
 
        buf_block_t*    block;
79
78
        rec_t*          rec;
80
79
        dict_index_t*   index;
81
80
        page_t*         page;
84
83
        ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
85
84
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
86
85
 
87
 
        block = btr_pcur_get_block(cursor);
88
86
        index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
89
87
 
90
88
        page_cursor = btr_pcur_get_page_cur(cursor);
93
91
        page = page_align(rec);
94
92
        offs = page_offset(rec);
95
93
 
96
 
        ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_S_FIX)
97
 
              || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
 
94
        ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 
95
                                MTR_MEMO_PAGE_S_FIX)
 
96
              || mtr_memo_contains(mtr, buf_block_align(page),
 
97
                                   MTR_MEMO_PAGE_X_FIX));
98
98
        ut_a(cursor->latch_mode != BTR_NO_LATCHES);
99
99
 
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);
139
139
 
140
 
        cursor->block_when_stored = block;
141
 
        cursor->modify_clock = buf_block_get_modify_clock(block);
 
140
        cursor->block_when_stored = buf_block_align(page);
 
141
        cursor->modify_clock = buf_block_get_modify_clock(
 
142
                cursor->block_when_stored);
142
143
}
143
144
 
144
145
/******************************************************************
145
146
Copies the stored position of a pcur to another pcur. */
146
 
UNIV_INTERN
 
147
 
147
148
void
148
149
btr_pcur_copy_stored_position(
149
150
/*==========================*/
183
184
GREATER than the user record which was the predecessor of the supremum.
184
185
(4) cursor was positioned before the first or after the last in an empty tree:
185
186
restores to before first or after the last in the tree. */
186
 
UNIV_INTERN
 
187
 
187
188
ibool
188
189
btr_pcur_restore_position(
189
190
/*======================*/
197
198
        mtr_t*          mtr)            /* in: mtr */
198
199
{
199
200
        dict_index_t*   index;
 
201
        page_t*         page;
200
202
        dtuple_t*       tuple;
201
203
        ulint           mode;
202
204
        ulint           old_mode;
215
217
                ut_error;
216
218
        }
217
219
 
218
 
        if (UNIV_UNLIKELY
219
 
            (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
220
 
             || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
 
220
        if (UNIV_UNLIKELY(
 
221
                    cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
 
222
                    || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
221
223
 
222
224
                /* In these cases we do not try an optimistic restoration,
223
225
                but always do a search */
226
228
                        cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
227
229
                        index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
228
230
 
229
 
                cursor->block_when_stored = btr_pcur_get_block(cursor);
 
231
                cursor->block_when_stored
 
232
                        = buf_block_align(btr_pcur_get_page(cursor));
230
233
 
231
234
                return(FALSE);
232
235
        }
234
237
        ut_a(cursor->old_rec);
235
238
        ut_a(cursor->old_n_fields);
236
239
 
 
240
        page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
 
241
 
237
242
        if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
238
243
            || UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
239
244
                /* Try optimistic restoration */
240
245
 
241
246
                if (UNIV_LIKELY(buf_page_optimistic_get(
242
247
                                        latch_mode,
243
 
                                        cursor->block_when_stored,
 
248
                                        cursor->block_when_stored, page,
244
249
                                        cursor->modify_clock, mtr))) {
245
250
                        cursor->pos_state = BTR_PCUR_IS_POSITIONED;
246
251
#ifdef UNIV_SYNC_DEBUG
247
 
                        buf_block_dbg_add_level(btr_pcur_get_block(cursor),
248
 
                                                SYNC_TREE_NODE);
 
252
                        buf_page_dbg_add_level(page, SYNC_TREE_NODE);
249
253
#endif /* UNIV_SYNC_DEBUG */
250
254
                        if (cursor->rel_pos == BTR_PCUR_ON) {
251
255
#ifdef UNIV_DEBUG
252
 
                                const rec_t*    rec;
253
 
                                const ulint*    offsets1;
254
 
                                const ulint*    offsets2;
 
256
                                rec_t*          rec;
 
257
                                ulint*          offsets1;
 
258
                                ulint*          offsets2;
255
259
#endif /* UNIV_DEBUG */
256
260
                                cursor->latch_mode = latch_mode;
257
261
#ifdef UNIV_DEBUG
303
307
        cursor->search_mode = old_mode;
304
308
 
305
309
        if (cursor->rel_pos == BTR_PCUR_ON
306
 
            && btr_pcur_is_on_user_rec(cursor)
 
310
            && btr_pcur_is_on_user_rec(cursor, mtr)
307
311
            && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
308
312
                                   rec_get_offsets(
309
313
                                           btr_pcur_get_rec(cursor), index,
313
317
                the cursor can now be on a different page! But we can retain
314
318
                the value of old_rec */
315
319
 
316
 
                cursor->block_when_stored = btr_pcur_get_block(cursor);
 
320
                cursor->block_when_stored = buf_block_align(
 
321
                        btr_pcur_get_page(cursor));
317
322
                cursor->modify_clock = buf_block_get_modify_clock(
318
323
                        cursor->block_when_stored);
319
324
                cursor->old_stored = BTR_PCUR_OLD_STORED;
340
345
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
341
346
made by the current mini-transaction to the data protected by the
342
347
cursor latch, as then the latch must not be released until mtr_commit. */
343
 
UNIV_INTERN
 
348
 
344
349
void
345
350
btr_pcur_release_leaf(
346
351
/*==================*/
347
352
        btr_pcur_t*     cursor, /* in: persistent cursor */
348
353
        mtr_t*          mtr)    /* in: mtr */
349
354
{
350
 
        buf_block_t*    block;
 
355
        page_t* page;
351
356
 
352
357
        ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
353
358
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
354
359
 
355
 
        block = btr_pcur_get_block(cursor);
 
360
        page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
356
361
 
357
 
        btr_leaf_page_release(block, cursor->latch_mode, mtr);
 
362
        btr_leaf_page_release(page, cursor->latch_mode, mtr);
358
363
 
359
364
        cursor->latch_mode = BTR_NO_LATCHES;
360
365
 
366
371
latch on the current page, and bufferunfixes it. Note that there must not be
367
372
modifications on the current page, as then the x-latch can be released only in
368
373
mtr_commit. */
369
 
UNIV_INTERN
 
374
 
370
375
void
371
376
btr_pcur_move_to_next_page(
372
377
/*=======================*/
374
379
                                last record of the current page */
375
380
        mtr_t*          mtr)    /* in: mtr */
376
381
{
377
 
        ulint           next_page_no;
378
 
        ulint           space;
379
 
        ulint           zip_size;
380
 
        page_t*         page;
381
 
        buf_block_t*    next_block;
382
 
        page_t*         next_page;
 
382
        ulint   next_page_no;
 
383
        ulint   space;
 
384
        page_t* page;
 
385
        page_t* next_page;
383
386
 
384
387
        ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
385
388
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
386
 
        ut_ad(btr_pcur_is_after_last_on_page(cursor));
 
389
        ut_ad(btr_pcur_is_after_last_on_page(cursor, mtr));
387
390
 
388
391
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
389
392
 
390
393
        page = btr_pcur_get_page(cursor);
 
394
 
391
395
        next_page_no = btr_page_get_next(page, mtr);
392
 
        space = buf_block_get_space(btr_pcur_get_block(cursor));
393
 
        zip_size = buf_block_get_zip_size(btr_pcur_get_block(cursor));
 
396
        space = buf_frame_get_space_id(page);
394
397
 
395
398
        ut_ad(next_page_no != FIL_NULL);
396
399
 
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);
 
400
        next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
400
401
#ifdef UNIV_BTR_DEBUG
 
402
        ut_a(btr_page_get_prev(next_page, mtr) == buf_frame_get_page_no(page));
 
403
#endif /* UNIV_BTR_DEBUG */
401
404
        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)));
404
 
#endif /* UNIV_BTR_DEBUG */
405
 
        next_block->check_index_page_at_flush = TRUE;
406
 
 
407
 
        btr_leaf_page_release(btr_pcur_get_block(cursor),
408
 
                              cursor->latch_mode, mtr);
409
 
 
410
 
        page_cur_set_before_first(next_block, btr_pcur_get_page_cur(cursor));
 
405
        buf_block_align(next_page)->check_index_page_at_flush = TRUE;
 
406
 
 
407
        btr_leaf_page_release(page, cursor->latch_mode, mtr);
 
408
 
 
409
        page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
411
410
 
412
411
        page_check_dir(next_page);
413
412
}
421
420
return, but it may happen that the cursor is not positioned on the last
422
421
record of any page, because the structure of the tree may have changed
423
422
during the time when the cursor had no latches. */
424
 
UNIV_INTERN
 
423
 
425
424
void
426
425
btr_pcur_move_backward_from_page(
427
426
/*=============================*/
429
428
                                record of the current page */
430
429
        mtr_t*          mtr)    /* in: mtr */
431
430
{
432
 
        ulint           prev_page_no;
433
 
        ulint           space;
434
 
        page_t*         page;
435
 
        buf_block_t*    prev_block;
436
 
        ulint           latch_mode;
437
 
        ulint           latch_mode2;
 
431
        ulint   prev_page_no;
 
432
        ulint   space;
 
433
        page_t* page;
 
434
        page_t* prev_page;
 
435
        ulint   latch_mode;
 
436
        ulint   latch_mode2;
438
437
 
439
438
        ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
440
439
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
441
 
        ut_ad(btr_pcur_is_before_first_on_page(cursor));
 
440
        ut_ad(btr_pcur_is_before_first_on_page(cursor, mtr));
442
441
        ut_ad(!btr_pcur_is_before_first_in_tree(cursor, mtr));
443
442
 
444
443
        latch_mode = cursor->latch_mode;
466
465
        page = btr_pcur_get_page(cursor);
467
466
 
468
467
        prev_page_no = btr_page_get_prev(page, mtr);
469
 
        space = buf_block_get_space(btr_pcur_get_block(cursor));
470
 
 
471
 
        if (prev_page_no == FIL_NULL) {
472
 
        } else if (btr_pcur_is_before_first_on_page(cursor)) {
473
 
 
474
 
                prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
475
 
 
476
 
                btr_leaf_page_release(btr_pcur_get_block(cursor),
477
 
                                      latch_mode, mtr);
478
 
 
479
 
                page_cur_set_after_last(prev_block,
 
468
        space = buf_frame_get_space_id(page);
 
469
 
 
470
        if (btr_pcur_is_before_first_on_page(cursor, mtr)
 
471
            && (prev_page_no != FIL_NULL)) {
 
472
 
 
473
                prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
 
474
 
 
475
                btr_leaf_page_release(page, latch_mode, mtr);
 
476
 
 
477
                page_cur_set_after_last(prev_page,
480
478
                                        btr_pcur_get_page_cur(cursor));
481
 
        } else {
 
479
        } else if (prev_page_no != FIL_NULL) {
482
480
 
483
481
                /* The repositioned cursor did not end on an infimum record on
484
482
                a page. Cursor repositioning acquired a latch also on the
485
483
                previous page, but we do not need the latch: release it. */
486
484
 
487
 
                prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
 
485
                prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
488
486
 
489
 
                btr_leaf_page_release(prev_block, latch_mode, mtr);
 
487
                btr_leaf_page_release(prev_page, latch_mode, mtr);
490
488
        }
491
489
 
492
490
        cursor->latch_mode = latch_mode;
497
495
/*************************************************************
498
496
Moves the persistent cursor to the previous record in the tree. If no records
499
497
are left, the cursor stays 'before first in tree'. */
500
 
UNIV_INTERN
 
498
 
501
499
ibool
502
500
btr_pcur_move_to_prev(
503
501
/*==================*/
512
510
 
513
511
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
514
512
 
515
 
        if (btr_pcur_is_before_first_on_page(cursor)) {
 
513
        if (btr_pcur_is_before_first_on_page(cursor, mtr)) {
516
514
 
517
515
                if (btr_pcur_is_before_first_in_tree(cursor, mtr)) {
518
516
 
524
522
                return(TRUE);
525
523
        }
526
524
 
527
 
        btr_pcur_move_to_prev_on_page(cursor);
 
525
        btr_pcur_move_to_prev_on_page(cursor, mtr);
528
526
 
529
527
        return(TRUE);
530
528
}
536
534
in the first case sets the cursor after last in tree, and in the latter case
537
535
before first in tree. The latching mode must be BTR_SEARCH_LEAF or
538
536
BTR_MODIFY_LEAF. */
539
 
UNIV_INTERN
 
537
 
540
538
void
541
539
btr_pcur_open_on_user_rec(
542
540
/*======================*/
543
541
        dict_index_t*   index,          /* in: index */
544
 
        const dtuple_t* tuple,          /* in: tuple on which search done */
 
542
        dtuple_t*       tuple,          /* in: tuple on which search done */
545
543
        ulint           mode,           /* in: PAGE_CUR_L, ... */
546
544
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF or
547
545
                                        BTR_MODIFY_LEAF */
553
551
 
554
552
        if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
555
553
 
556
 
                if (btr_pcur_is_after_last_on_page(cursor)) {
 
554
                if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
557
555
 
558
556
                        btr_pcur_move_to_next_user_rec(cursor, mtr);
559
557
                }