~gaul/percona-data-recovery-tool-for-innodb/prerequisites

« back to all changes in this revision

Viewing changes to mysql-source/innobase/include/btr0pcur.ic

  • Committer: Aleksandr Kuzminsky
  • Date: 2010-01-14 13:05:06 UTC
  • mfrom: (1.1.1 page-signature-check)
  • Revision ID: aleksandr.kuzminsky@percona.com-20100114130506-72t6jxtll15gk3pp
Added InnoDB page signature check.
At the beginning of InnoDB page (type FIL_PAGE_INODE) there are infimum and supremum records.
They are located in fixed position depending on InnoDB page format(REDUNDANT (4.x and 5.x versions) or COMPACT(5.x only)).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
The index tree persistent cursor
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 2/23/1996 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
 
 
10
/*************************************************************
 
11
Gets the rel_pos field for a cursor whose position has been stored. */
 
12
UNIV_INLINE
 
13
ulint
 
14
btr_pcur_get_rel_pos(
 
15
/*=================*/
 
16
                                /* out: BTR_PCUR_ON, ... */
 
17
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
18
{
 
19
        ut_ad(cursor);
 
20
        ut_ad(cursor->old_rec);
 
21
        ut_ad(cursor->old_stored == BTR_PCUR_OLD_STORED);
 
22
        ut_ad(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
 
23
                        || cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
24
 
 
25
        return(cursor->rel_pos);
 
26
}
 
27
 
 
28
/*************************************************************
 
29
Sets the mtr field for a pcur. */
 
30
UNIV_INLINE
 
31
void
 
32
btr_pcur_set_mtr(
 
33
/*=============*/
 
34
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
35
        mtr_t*          mtr)    /* in, own: mtr */
 
36
{
 
37
        ut_ad(cursor);
 
38
 
 
39
        cursor->mtr = mtr;
 
40
}
 
41
 
 
42
/*************************************************************
 
43
Gets the mtr field for a pcur. */
 
44
UNIV_INLINE
 
45
mtr_t*
 
46
btr_pcur_get_mtr(
 
47
/*=============*/
 
48
                                /* out: mtr */
 
49
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
50
{
 
51
        ut_ad(cursor);
 
52
 
 
53
        return(cursor->mtr);
 
54
}
 
55
 
 
56
/*************************************************************
 
57
Returns the btr cursor component of a persistent cursor. */
 
58
UNIV_INLINE
 
59
btr_cur_t*
 
60
btr_pcur_get_btr_cur(
 
61
/*=================*/
 
62
                                /* out: pointer to btr cursor component */
 
63
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
64
{
 
65
        return(&(cursor->btr_cur));
 
66
}
 
67
 
 
68
/*************************************************************
 
69
Returns the page cursor component of a persistent cursor. */
 
70
UNIV_INLINE
 
71
page_cur_t*
 
72
btr_pcur_get_page_cur(
 
73
/*==================*/
 
74
                                /* out: pointer to page cursor component */
 
75
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
76
{
 
77
        return(btr_cur_get_page_cur(&(cursor->btr_cur)));
 
78
}
 
79
 
 
80
/*************************************************************
 
81
Returns the page of a persistent cursor. */
 
82
UNIV_INLINE
 
83
page_t*
 
84
btr_pcur_get_page(
 
85
/*==============*/
 
86
                                /* out: pointer to the page */
 
87
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
88
{
 
89
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
90
 
 
91
        return(page_cur_get_page(btr_pcur_get_page_cur(cursor)));
 
92
}
 
93
 
 
94
/*************************************************************
 
95
Returns the record of a persistent cursor. */
 
96
UNIV_INLINE
 
97
rec_t*
 
98
btr_pcur_get_rec(
 
99
/*=============*/
 
100
                                /* out: pointer to the record */
 
101
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
102
{
 
103
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
104
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
105
        
 
106
        return(page_cur_get_rec(btr_pcur_get_page_cur(cursor)));
 
107
}
 
108
 
 
109
/******************************************************************
 
110
Gets the up_match value for a pcur after a search. */
 
111
UNIV_INLINE
 
112
ulint
 
113
btr_pcur_get_up_match(
 
114
/*==================*/
 
115
                                /* out: number of matched fields at the cursor
 
116
                                or to the right if search mode was PAGE_CUR_GE,
 
117
                                otherwise undefined */
 
118
        btr_pcur_t*     cursor) /* in: memory buffer for persistent cursor */
 
119
{
 
120
        btr_cur_t*      btr_cursor;
 
121
 
 
122
        ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
 
123
                        || (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
 
124
 
 
125
        btr_cursor = btr_pcur_get_btr_cur(cursor);
 
126
 
 
127
        ut_ad(btr_cursor->up_match != ULINT_UNDEFINED);
 
128
 
 
129
        return(btr_cursor->up_match);
 
130
}
 
131
 
 
132
/******************************************************************
 
133
Gets the low_match value for a pcur after a search. */
 
134
UNIV_INLINE
 
135
ulint
 
136
btr_pcur_get_low_match(
 
137
/*===================*/
 
138
                                /* out: number of matched fields at the cursor
 
139
                                or to the right if search mode was PAGE_CUR_LE,
 
140
                                otherwise undefined */
 
141
        btr_pcur_t*     cursor) /* in: memory buffer for persistent cursor */
 
142
{
 
143
        btr_cur_t*      btr_cursor;
 
144
 
 
145
        ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
 
146
                        || (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
 
147
 
 
148
        btr_cursor = btr_pcur_get_btr_cur(cursor);
 
149
        ut_ad(btr_cursor->low_match != ULINT_UNDEFINED);
 
150
 
 
151
        return(btr_cursor->low_match);
 
152
}
 
153
 
 
154
/*************************************************************
 
155
Checks if the persistent cursor is after the last user record on 
 
156
a page. */
 
157
UNIV_INLINE
 
158
ibool
 
159
btr_pcur_is_after_last_on_page(
 
160
/*===========================*/
 
161
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
162
        mtr_t*          mtr)    /* in: mtr */
 
163
{
 
164
        UT_NOT_USED(mtr);
 
165
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
166
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
167
        
 
168
        return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
 
169
}
 
170
 
 
171
/*************************************************************
 
172
Checks if the persistent cursor is before the first user record on 
 
173
a page. */
 
174
UNIV_INLINE
 
175
ibool
 
176
btr_pcur_is_before_first_on_page(
 
177
/*=============================*/
 
178
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
179
        mtr_t*          mtr)    /* in: mtr */
 
180
{
 
181
        UT_NOT_USED(mtr);
 
182
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
183
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
184
        
 
185
        return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
 
186
}
 
187
 
 
188
/*************************************************************
 
189
Checks if the persistent cursor is on a user record. */
 
190
UNIV_INLINE
 
191
ibool
 
192
btr_pcur_is_on_user_rec(
 
193
/*====================*/
 
194
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
195
        mtr_t*          mtr)    /* in: mtr */
 
196
{
 
197
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
198
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
199
        
 
200
        if ((btr_pcur_is_before_first_on_page(cursor, mtr))
 
201
            || (btr_pcur_is_after_last_on_page(cursor, mtr))) {
 
202
 
 
203
                return(FALSE);
 
204
        }
 
205
 
 
206
        return(TRUE);
 
207
}
 
208
 
 
209
/*************************************************************
 
210
Checks if the persistent cursor is before the first user record in
 
211
the index tree. */
 
212
UNIV_INLINE
 
213
ibool
 
214
btr_pcur_is_before_first_in_tree(
 
215
/*=============================*/
 
216
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
217
        mtr_t*          mtr)    /* in: mtr */
 
218
{
 
219
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
220
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
221
        
 
222
        if (btr_page_get_prev(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
 
223
 
 
224
                return(FALSE);
 
225
        }
 
226
 
 
227
        return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
 
228
}
 
229
 
 
230
/*************************************************************
 
231
Checks if the persistent cursor is after the last user record in
 
232
the index tree. */
 
233
UNIV_INLINE
 
234
ibool
 
235
btr_pcur_is_after_last_in_tree(
 
236
/*===========================*/
 
237
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
238
        mtr_t*          mtr)    /* in: mtr */
 
239
{
 
240
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
241
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
242
        
 
243
        if (btr_page_get_next(btr_pcur_get_page(cursor), mtr) != FIL_NULL) {
 
244
 
 
245
                return(FALSE);
 
246
        }
 
247
 
 
248
        return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
 
249
}
 
250
 
 
251
/*************************************************************
 
252
Moves the persistent cursor to the next record on the same page. */
 
253
UNIV_INLINE
 
254
void
 
255
btr_pcur_move_to_next_on_page(
 
256
/*==========================*/
 
257
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
258
        mtr_t*          mtr)    /* in: mtr */
 
259
{
 
260
        UT_NOT_USED(mtr);
 
261
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
262
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
263
        
 
264
        page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
 
265
 
 
266
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
267
}
 
268
 
 
269
/*************************************************************
 
270
Moves the persistent cursor to the previous record on the same page. */
 
271
UNIV_INLINE
 
272
void
 
273
btr_pcur_move_to_prev_on_page(
 
274
/*==========================*/
 
275
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
276
        mtr_t*          mtr)    /* in: mtr */
 
277
{
 
278
        UT_NOT_USED(mtr);
 
279
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
280
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
281
        
 
282
        page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
 
283
 
 
284
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
285
}
 
286
 
 
287
/*************************************************************
 
288
Moves the persistent cursor to the last record on the same page. */
 
289
UNIV_INLINE
 
290
void
 
291
btr_pcur_move_to_last_on_page(
 
292
/*==========================*/
 
293
        btr_pcur_t*     cursor, /* in: persistent cursor */
 
294
        mtr_t*          mtr)    /* in: mtr */
 
295
{
 
296
        UT_NOT_USED(mtr);
 
297
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
298
        
 
299
        page_cur_set_after_last(buf_frame_align(btr_pcur_get_rec(cursor)),
 
300
                                btr_pcur_get_page_cur(cursor));
 
301
 
 
302
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
303
}
 
304
 
 
305
/*************************************************************
 
306
Moves the persistent cursor to the next user record in the tree. If no user
 
307
records are left, the cursor ends up 'after last in tree'. */
 
308
UNIV_INLINE
 
309
ibool
 
310
btr_pcur_move_to_next_user_rec(
 
311
/*===========================*/
 
312
                                /* out: TRUE if the cursor moved forward,
 
313
                                ending on a user record */
 
314
        btr_pcur_t*     cursor, /* in: persistent cursor; NOTE that the
 
315
                                function may release the page latch */
 
316
        mtr_t*          mtr)    /* in: mtr */
 
317
{
 
318
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
319
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
320
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
321
loop:
 
322
        if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
 
323
 
 
324
                if (btr_pcur_is_after_last_in_tree(cursor, mtr)) {
 
325
 
 
326
                        return(FALSE);
 
327
                }
 
328
 
 
329
                btr_pcur_move_to_next_page(cursor, mtr);
 
330
        } else {
 
331
                btr_pcur_move_to_next_on_page(cursor, mtr);
 
332
        }
 
333
 
 
334
        if (btr_pcur_is_on_user_rec(cursor, mtr)) {
 
335
 
 
336
                return(TRUE);
 
337
        }
 
338
 
 
339
        goto loop;
 
340
}
 
341
 
 
342
/*************************************************************
 
343
Moves the persistent cursor to the next record in the tree. If no records are
 
344
left, the cursor stays 'after last in tree'. */
 
345
UNIV_INLINE
 
346
ibool
 
347
btr_pcur_move_to_next(
 
348
/*==================*/
 
349
                                /* out: TRUE if the cursor was not after last
 
350
                                in tree */
 
351
        btr_pcur_t*     cursor, /* in: persistent cursor; NOTE that the
 
352
                                function may release the page latch */
 
353
        mtr_t*          mtr)    /* in: mtr */
 
354
{
 
355
        ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
356
        ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
357
 
 
358
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
359
        
 
360
        if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
 
361
 
 
362
                if (btr_pcur_is_after_last_in_tree(cursor, mtr)) {
 
363
 
 
364
                        return(FALSE);
 
365
                }
 
366
                
 
367
                btr_pcur_move_to_next_page(cursor, mtr);
 
368
 
 
369
                return(TRUE);
 
370
        }
 
371
 
 
372
        btr_pcur_move_to_next_on_page(cursor, mtr);
 
373
 
 
374
        return(TRUE);   
 
375
}
 
376
 
 
377
/******************************************************************
 
378
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
 
379
that is, the cursor becomes detached. If there have been modifications
 
380
to the page where pcur is positioned, this can be used instead of
 
381
btr_pcur_release_leaf. Function btr_pcur_store_position should be used
 
382
before calling this, if restoration of cursor is wanted later. */
 
383
UNIV_INLINE
 
384
void
 
385
btr_pcur_commit(
 
386
/*============*/
 
387
        btr_pcur_t*     pcur)   /* in: persistent cursor */
 
388
{
 
389
        ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
 
390
 
 
391
        pcur->latch_mode = BTR_NO_LATCHES;      
 
392
 
 
393
        mtr_commit(pcur->mtr);
 
394
 
 
395
        pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
 
396
}       
 
397
 
 
398
/******************************************************************
 
399
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
 
400
UNIV_INLINE
 
401
void
 
402
btr_pcur_commit_specify_mtr(
 
403
/*========================*/
 
404
        btr_pcur_t*     pcur,   /* in: persistent cursor */
 
405
        mtr_t*          mtr)    /* in: mtr to commit */
 
406
{
 
407
        ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
 
408
 
 
409
        pcur->latch_mode = BTR_NO_LATCHES;      
 
410
 
 
411
        mtr_commit(mtr);
 
412
 
 
413
        pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
 
414
}       
 
415
 
 
416
/******************************************************************
 
417
Sets the pcur latch mode to BTR_NO_LATCHES. */
 
418
UNIV_INLINE
 
419
void
 
420
btr_pcur_detach(
 
421
/*============*/
 
422
        btr_pcur_t*     pcur)   /* in: persistent cursor */
 
423
{
 
424
        ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
 
425
        
 
426
        pcur->latch_mode = BTR_NO_LATCHES;
 
427
 
 
428
        pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
 
429
}
 
430
 
 
431
/******************************************************************
 
432
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
 
433
UNIV_INLINE
 
434
ibool
 
435
btr_pcur_is_detached(
 
436
/*=================*/
 
437
                                /* out: TRUE if detached */
 
438
        btr_pcur_t*     pcur)   /* in: persistent cursor */
 
439
{
 
440
        if (pcur->latch_mode == BTR_NO_LATCHES) {
 
441
 
 
442
                return(TRUE);
 
443
        }       
 
444
 
 
445
        return(FALSE);
 
446
}
 
447
 
 
448
/******************************************************************
 
449
Sets the old_rec_buf field to NULL. */
 
450
UNIV_INLINE
 
451
void
 
452
btr_pcur_init(
 
453
/*==========*/
 
454
        btr_pcur_t*     pcur)   /* in: persistent cursor */
 
455
{       
 
456
        pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
457
        pcur->old_rec_buf = NULL;
 
458
        pcur->old_rec = NULL;
 
459
}
 
460
 
 
461
/******************************************************************
 
462
Initializes and opens a persistent cursor to an index tree. It should be
 
463
closed with btr_pcur_close. */
 
464
UNIV_INLINE
 
465
void
 
466
btr_pcur_open(
 
467
/*==========*/
 
468
        dict_index_t*   index,  /* in: index */
 
469
        dtuple_t*       tuple,  /* in: tuple on which search done */
 
470
        ulint           mode,   /* in: PAGE_CUR_L, ...;
 
471
                                NOTE that if the search is made using a unique
 
472
                                prefix of a record, mode should be
 
473
                                PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
 
474
                                may end up on the previous page from the
 
475
                                record! */
 
476
        ulint           latch_mode,/* in: BTR_SEARCH_LEAF, ... */
 
477
        btr_pcur_t*     cursor, /* in: memory buffer for persistent cursor */
 
478
        mtr_t*          mtr)    /* in: mtr */
 
479
{
 
480
        btr_cur_t*      btr_cursor;
 
481
 
 
482
        /* Initialize the cursor */
 
483
 
 
484
        btr_pcur_init(cursor);
 
485
 
 
486
        cursor->latch_mode = latch_mode;
 
487
        cursor->search_mode = mode;
 
488
        
 
489
        /* Search with the tree cursor */
 
490
 
 
491
        btr_cursor = btr_pcur_get_btr_cur(cursor);
 
492
 
 
493
        btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
 
494
                                                        btr_cursor, 0, mtr);
 
495
        cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 
496
 
 
497
        cursor->trx_if_known = NULL;
 
498
}
 
499
 
 
500
/******************************************************************
 
501
Opens an persistent cursor to an index tree without initializing the
 
502
cursor. */
 
503
UNIV_INLINE
 
504
void
 
505
btr_pcur_open_with_no_init(
 
506
/*=======================*/
 
507
        dict_index_t*   index,  /* in: index */
 
508
        dtuple_t*       tuple,  /* in: tuple on which search done */
 
509
        ulint           mode,   /* in: PAGE_CUR_L, ...;
 
510
                                NOTE that if the search is made using a unique
 
511
                                prefix of a record, mode should be
 
512
                                PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
 
513
                                may end up on the previous page of the
 
514
                                record! */
 
515
        ulint           latch_mode,/* in: BTR_SEARCH_LEAF, ...;
 
516
                                NOTE that if has_search_latch != 0 then
 
517
                                we maybe do not acquire a latch on the cursor
 
518
                                page, but assume that the caller uses his
 
519
                                btr search latch to protect the record! */
 
520
        btr_pcur_t*     cursor, /* in: memory buffer for persistent cursor */
 
521
        ulint           has_search_latch,/* in: latch mode the caller
 
522
                                currently has on btr_search_latch:
 
523
                                RW_S_LATCH, or 0 */
 
524
        mtr_t*          mtr)    /* in: mtr */
 
525
{
 
526
        btr_cur_t*      btr_cursor;
 
527
 
 
528
        cursor->latch_mode = latch_mode;
 
529
        cursor->search_mode = mode;
 
530
        
 
531
        /* Search with the tree cursor */
 
532
 
 
533
        btr_cursor = btr_pcur_get_btr_cur(cursor);
 
534
 
 
535
        btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
 
536
                                        btr_cursor, has_search_latch, mtr);
 
537
        cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 
538
 
 
539
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
540
 
 
541
        cursor->trx_if_known = NULL;
 
542
}
 
543
 
 
544
/*********************************************************************
 
545
Opens a persistent cursor at either end of an index. */
 
546
UNIV_INLINE
 
547
void
 
548
btr_pcur_open_at_index_side(
 
549
/*========================*/
 
550
        ibool           from_left,      /* in: TRUE if open to the low end,
 
551
                                        FALSE if to the high end */
 
552
        dict_index_t*   index,          /* in: index */
 
553
        ulint           latch_mode,     /* in: latch mode */
 
554
        btr_pcur_t*     pcur,           /* in: cursor */
 
555
        ibool           do_init,        /* in: TRUE if should be initialized */
 
556
        mtr_t*          mtr)            /* in: mtr */
 
557
{
 
558
        pcur->latch_mode = latch_mode;
 
559
 
 
560
        if (from_left) {
 
561
                pcur->search_mode = PAGE_CUR_G;
 
562
        } else {
 
563
                pcur->search_mode = PAGE_CUR_L;
 
564
        }
 
565
 
 
566
        if (do_init) {
 
567
                btr_pcur_init(pcur);
 
568
        }
 
569
 
 
570
        btr_cur_open_at_index_side(from_left, index, latch_mode,
 
571
                                        btr_pcur_get_btr_cur(pcur), mtr);
 
572
        pcur->pos_state = BTR_PCUR_IS_POSITIONED;
 
573
 
 
574
        pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
575
 
 
576
        pcur->trx_if_known = NULL;
 
577
}
 
578
 
 
579
/**************************************************************************
 
580
Positions a cursor at a randomly chosen position within a B-tree. */
 
581
UNIV_INLINE
 
582
void
 
583
btr_pcur_open_at_rnd_pos(
 
584
/*=====================*/
 
585
        dict_index_t*   index,          /* in: index */
 
586
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF, ... */
 
587
        btr_pcur_t*     cursor,         /* in/out: B-tree pcur */
 
588
        mtr_t*          mtr)            /* in: mtr */
 
589
{
 
590
        /* Initialize the cursor */
 
591
 
 
592
        cursor->latch_mode = latch_mode;
 
593
        cursor->search_mode = PAGE_CUR_G;
 
594
        
 
595
        btr_pcur_init(cursor);
 
596
 
 
597
        btr_cur_open_at_rnd_pos(index, latch_mode,
 
598
                                        btr_pcur_get_btr_cur(cursor), mtr);
 
599
        cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 
600
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
601
 
 
602
        cursor->trx_if_known = NULL;
 
603
}
 
604
        
 
605
/******************************************************************
 
606
Frees the possible memory heap of a persistent cursor and sets the latch
 
607
mode of the persistent cursor to BTR_NO_LATCHES. */
 
608
UNIV_INLINE
 
609
void
 
610
btr_pcur_close(
 
611
/*===========*/
 
612
        btr_pcur_t*     cursor) /* in: persistent cursor */
 
613
{
 
614
        if (cursor->old_rec_buf != NULL) {
 
615
 
 
616
                mem_free(cursor->old_rec_buf);
 
617
 
 
618
                cursor->old_rec = NULL;
 
619
                cursor->old_rec_buf = NULL;
 
620
        }
 
621
 
 
622
        cursor->btr_cur.page_cur.rec = NULL;
 
623
        cursor->old_rec = NULL;
 
624
        cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
 
625
        
 
626
        cursor->latch_mode = BTR_NO_LATCHES;
 
627
        cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
 
628
 
 
629
        cursor->trx_if_known = NULL;
 
630
}