~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/fut/fut0lst.c

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#endif
14
14
 
15
15
#include "buf0buf.h"
16
 
 
 
16
#include "page0page.h"
17
17
 
18
18
/************************************************************************
19
19
Adds a node to an empty list. */
32
32
 
33
33
        ut_ad(mtr && base && node);
34
34
        ut_ad(base != node);
35
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
36
 
                                MTR_MEMO_PAGE_X_FIX));
37
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node),
38
 
                                MTR_MEMO_PAGE_X_FIX));
 
35
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
36
        ut_ad(mtr_memo_contains_page(mtr, node, MTR_MEMO_PAGE_X_FIX));
39
37
        len = flst_get_len(base, mtr);
40
38
        ut_a(len == 0);
41
39
 
55
53
 
56
54
/************************************************************************
57
55
Adds a node as the last node in a list. */
58
 
 
 
56
UNIV_INTERN
59
57
void
60
58
flst_add_last(
61
59
/*==========*/
71
69
 
72
70
        ut_ad(mtr && base && node);
73
71
        ut_ad(base != node);
74
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
75
 
                                MTR_MEMO_PAGE_X_FIX));
76
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node),
77
 
                                MTR_MEMO_PAGE_X_FIX));
 
72
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
73
        ut_ad(mtr_memo_contains_page(mtr, node, MTR_MEMO_PAGE_X_FIX));
78
74
        len = flst_get_len(base, mtr);
79
75
        last_addr = flst_get_last(base, mtr);
80
76
 
83
79
        /* If the list is not empty, call flst_insert_after */
84
80
        if (len != 0) {
85
81
                if (last_addr.page == node_addr.page) {
86
 
                        last_node = buf_frame_align(node) + last_addr.boffset;
 
82
                        last_node = page_align(node) + last_addr.boffset;
87
83
                } else {
88
 
                        last_node = fut_get_ptr(space, last_addr, RW_X_LATCH,
89
 
                                                mtr);
 
84
                        ulint   zip_size = fil_space_get_zip_size(space);
 
85
 
 
86
                        last_node = fut_get_ptr(space, zip_size, last_addr,
 
87
                                                RW_X_LATCH, mtr);
90
88
                }
91
89
 
92
90
                flst_insert_after(base, last_node, node, mtr);
98
96
 
99
97
/************************************************************************
100
98
Adds a node as the first node in a list. */
101
 
 
 
99
UNIV_INTERN
102
100
void
103
101
flst_add_first(
104
102
/*===========*/
114
112
 
115
113
        ut_ad(mtr && base && node);
116
114
        ut_ad(base != node);
117
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
118
 
                                MTR_MEMO_PAGE_X_FIX));
119
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node),
120
 
                                MTR_MEMO_PAGE_X_FIX));
 
115
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
116
        ut_ad(mtr_memo_contains_page(mtr, node, MTR_MEMO_PAGE_X_FIX));
121
117
        len = flst_get_len(base, mtr);
122
118
        first_addr = flst_get_first(base, mtr);
123
119
 
126
122
        /* If the list is not empty, call flst_insert_before */
127
123
        if (len != 0) {
128
124
                if (first_addr.page == node_addr.page) {
129
 
                        first_node = buf_frame_align(node)
130
 
                                + first_addr.boffset;
 
125
                        first_node = page_align(node) + first_addr.boffset;
131
126
                } else {
132
 
                        first_node = fut_get_ptr(space, first_addr,
 
127
                        ulint   zip_size = fil_space_get_zip_size(space);
 
128
 
 
129
                        first_node = fut_get_ptr(space, zip_size, first_addr,
133
130
                                                 RW_X_LATCH, mtr);
134
131
                }
135
132
 
142
139
 
143
140
/************************************************************************
144
141
Inserts a node after another in a list. */
145
 
 
 
142
UNIV_INTERN
146
143
void
147
144
flst_insert_after(
148
145
/*==============*/
162
159
        ut_ad(base != node1);
163
160
        ut_ad(base != node2);
164
161
        ut_ad(node2 != node1);
165
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
166
 
                                MTR_MEMO_PAGE_X_FIX));
167
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node1),
168
 
                                MTR_MEMO_PAGE_X_FIX));
169
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
170
 
                                MTR_MEMO_PAGE_X_FIX));
 
162
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
163
        ut_ad(mtr_memo_contains_page(mtr, node1, MTR_MEMO_PAGE_X_FIX));
 
164
        ut_ad(mtr_memo_contains_page(mtr, node2, MTR_MEMO_PAGE_X_FIX));
171
165
 
172
166
        buf_ptr_get_fsp_addr(node1, &space, &node1_addr);
173
167
        buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
180
174
 
181
175
        if (!fil_addr_is_null(node3_addr)) {
182
176
                /* Update prev field of node3 */
183
 
                node3 = fut_get_ptr(space, node3_addr, RW_X_LATCH, mtr);
 
177
                ulint   zip_size = fil_space_get_zip_size(space);
 
178
 
 
179
                node3 = fut_get_ptr(space, zip_size,
 
180
                                    node3_addr, RW_X_LATCH, mtr);
184
181
                flst_write_addr(node3 + FLST_PREV, node2_addr, mtr);
185
182
        } else {
186
183
                /* node1 was last in list: update last field in base */
197
194
 
198
195
/************************************************************************
199
196
Inserts a node before another in a list. */
200
 
 
 
197
UNIV_INTERN
201
198
void
202
199
flst_insert_before(
203
200
/*===============*/
217
214
        ut_ad(base != node2);
218
215
        ut_ad(base != node3);
219
216
        ut_ad(node2 != node3);
220
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
221
 
                                MTR_MEMO_PAGE_X_FIX));
222
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
223
 
                                MTR_MEMO_PAGE_X_FIX));
224
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node3),
225
 
                                MTR_MEMO_PAGE_X_FIX));
 
217
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
218
        ut_ad(mtr_memo_contains_page(mtr, node2, MTR_MEMO_PAGE_X_FIX));
 
219
        ut_ad(mtr_memo_contains_page(mtr, node3, MTR_MEMO_PAGE_X_FIX));
226
220
 
227
221
        buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
228
222
        buf_ptr_get_fsp_addr(node3, &space, &node3_addr);
234
228
        flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr);
235
229
 
236
230
        if (!fil_addr_is_null(node1_addr)) {
 
231
                ulint   zip_size = fil_space_get_zip_size(space);
237
232
                /* Update next field of node1 */
238
 
                node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH, mtr);
 
233
                node1 = fut_get_ptr(space, zip_size, node1_addr,
 
234
                                    RW_X_LATCH, mtr);
239
235
                flst_write_addr(node1 + FLST_NEXT, node2_addr, mtr);
240
236
        } else {
241
237
                /* node3 was first in list: update first field in base */
252
248
 
253
249
/************************************************************************
254
250
Removes a node. */
255
 
 
 
251
UNIV_INTERN
256
252
void
257
253
flst_remove(
258
254
/*========*/
261
257
        mtr_t*                  mtr)    /* in: mini-transaction handle */
262
258
{
263
259
        ulint           space;
 
260
        ulint           zip_size;
264
261
        flst_node_t*    node1;
265
262
        fil_addr_t      node1_addr;
266
263
        fil_addr_t      node2_addr;
269
266
        ulint           len;
270
267
 
271
268
        ut_ad(mtr && node2 && base);
272
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
273
 
                                MTR_MEMO_PAGE_X_FIX));
274
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
275
 
                                MTR_MEMO_PAGE_X_FIX));
 
269
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
270
        ut_ad(mtr_memo_contains_page(mtr, node2, MTR_MEMO_PAGE_X_FIX));
276
271
 
277
272
        buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
 
273
        zip_size = fil_space_get_zip_size(space);
278
274
 
279
275
        node1_addr = flst_get_prev_addr(node2, mtr);
280
276
        node3_addr = flst_get_next_addr(node2, mtr);
285
281
 
286
282
                if (node1_addr.page == node2_addr.page) {
287
283
 
288
 
                        node1 = buf_frame_align(node2) + node1_addr.boffset;
 
284
                        node1 = page_align(node2) + node1_addr.boffset;
289
285
                } else {
290
 
                        node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH,
291
 
                                            mtr);
 
286
                        node1 = fut_get_ptr(space, zip_size,
 
287
                                            node1_addr, RW_X_LATCH, mtr);
292
288
                }
293
289
 
294
290
                ut_ad(node1 != node2);
304
300
 
305
301
                if (node3_addr.page == node2_addr.page) {
306
302
 
307
 
                        node3 = buf_frame_align(node2) + node3_addr.boffset;
 
303
                        node3 = page_align(node2) + node3_addr.boffset;
308
304
                } else {
309
 
                        node3 = fut_get_ptr(space, node3_addr, RW_X_LATCH,
310
 
                                            mtr);
 
305
                        node3 = fut_get_ptr(space, zip_size,
 
306
                                            node3_addr, RW_X_LATCH, mtr);
311
307
                }
312
308
 
313
309
                ut_ad(node2 != node3);
329
325
Cuts off the tail of the list, including the node given. The number of
330
326
nodes which will be removed must be provided by the caller, as this function
331
327
does not measure the length of the tail. */
332
 
 
 
328
UNIV_INTERN
333
329
void
334
330
flst_cut_end(
335
331
/*=========*/
346
342
        ulint           len;
347
343
 
348
344
        ut_ad(mtr && node2 && base);
349
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
350
 
                                MTR_MEMO_PAGE_X_FIX));
351
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
352
 
                                MTR_MEMO_PAGE_X_FIX));
 
345
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
346
        ut_ad(mtr_memo_contains_page(mtr, node2, MTR_MEMO_PAGE_X_FIX));
353
347
        ut_ad(n_nodes > 0);
354
348
 
355
349
        buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
362
356
 
363
357
                if (node1_addr.page == node2_addr.page) {
364
358
 
365
 
                        node1 = buf_frame_align(node2) + node1_addr.boffset;
 
359
                        node1 = page_align(node2) + node1_addr.boffset;
366
360
                } else {
367
 
                        node1 = fut_get_ptr(space, node1_addr, RW_X_LATCH,
368
 
                                            mtr);
 
361
                        node1 = fut_get_ptr(space,
 
362
                                            fil_space_get_zip_size(space),
 
363
                                            node1_addr, RW_X_LATCH, mtr);
369
364
                }
370
365
 
371
366
                flst_write_addr(node1 + FLST_NEXT, fil_addr_null, mtr);
387
382
Cuts off the tail of the list, not including the given node. The number of
388
383
nodes which will be removed must be provided by the caller, as this function
389
384
does not measure the length of the tail. */
390
 
 
 
385
UNIV_INTERN
391
386
void
392
387
flst_truncate_end(
393
388
/*==============*/
401
396
        ulint           space;
402
397
 
403
398
        ut_ad(mtr && node2 && base);
404
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
405
 
                                MTR_MEMO_PAGE_X_FIX));
406
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(node2),
407
 
                                MTR_MEMO_PAGE_X_FIX));
 
399
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
400
        ut_ad(mtr_memo_contains_page(mtr, node2, MTR_MEMO_PAGE_X_FIX));
408
401
        if (n_nodes == 0) {
409
402
 
410
403
                ut_ad(fil_addr_is_null(flst_get_next_addr(node2, mtr)));
428
421
 
429
422
/************************************************************************
430
423
Validates a file-based list. */
431
 
 
 
424
UNIV_INTERN
432
425
ibool
433
426
flst_validate(
434
427
/*==========*/
435
428
                                        /* out: TRUE if ok */
436
 
        flst_base_node_t*       base,   /* in: pointer to base node of list */
 
429
        const flst_base_node_t* base,   /* in: pointer to base node of list */
437
430
        mtr_t*                  mtr1)   /* in: mtr */
438
431
{
439
 
        ulint           space;
440
 
        flst_node_t*    node;
441
 
        fil_addr_t      node_addr;
442
 
        fil_addr_t      base_addr;
443
 
        ulint           len;
444
 
        ulint           i;
445
 
        mtr_t           mtr2;
 
432
        ulint                   space;
 
433
        ulint                   zip_size;
 
434
        const flst_node_t*      node;
 
435
        fil_addr_t              node_addr;
 
436
        fil_addr_t              base_addr;
 
437
        ulint                   len;
 
438
        ulint                   i;
 
439
        mtr_t                   mtr2;
446
440
 
447
441
        ut_ad(base);
448
 
        ut_ad(mtr_memo_contains(mtr1, buf_block_align(base),
449
 
                                MTR_MEMO_PAGE_X_FIX));
 
442
        ut_ad(mtr_memo_contains_page(mtr1, base, MTR_MEMO_PAGE_X_FIX));
450
443
 
451
444
        /* We use two mini-transaction handles: the first is used to
452
445
        lock the base node, and prevent other threads from modifying the
457
450
 
458
451
        /* Find out the space id */
459
452
        buf_ptr_get_fsp_addr(base, &space, &base_addr);
 
453
        zip_size = fil_space_get_zip_size(space);
460
454
 
461
455
        len = flst_get_len(base, mtr1);
462
456
        node_addr = flst_get_first(base, mtr1);
464
458
        for (i = 0; i < len; i++) {
465
459
                mtr_start(&mtr2);
466
460
 
467
 
                node = fut_get_ptr(space, node_addr, RW_X_LATCH, &mtr2);
 
461
                node = fut_get_ptr(space, zip_size,
 
462
                                   node_addr, RW_X_LATCH, &mtr2);
468
463
                node_addr = flst_get_next_addr(node, &mtr2);
469
464
 
470
465
                mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
478
473
        for (i = 0; i < len; i++) {
479
474
                mtr_start(&mtr2);
480
475
 
481
 
                node = fut_get_ptr(space, node_addr, RW_X_LATCH, &mtr2);
 
476
                node = fut_get_ptr(space, zip_size,
 
477
                                   node_addr, RW_X_LATCH, &mtr2);
482
478
                node_addr = flst_get_prev_addr(node, &mtr2);
483
479
 
484
480
                mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
492
488
 
493
489
/************************************************************************
494
490
Prints info of a file-based list. */
495
 
 
 
491
UNIV_INTERN
496
492
void
497
493
flst_print(
498
494
/*=======*/
499
 
        flst_base_node_t*       base,   /* in: pointer to base node of list */
 
495
        const flst_base_node_t* base,   /* in: pointer to base node of list */
500
496
        mtr_t*                  mtr)    /* in: mtr */
501
497
{
502
 
        buf_frame_t*    frame;
503
 
        ulint           len;
 
498
        const buf_frame_t*      frame;
 
499
        ulint                   len;
504
500
 
505
501
        ut_ad(base && mtr);
506
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(base),
507
 
                                MTR_MEMO_PAGE_X_FIX));
508
 
        frame = buf_frame_align(base);
 
502
        ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
 
503
        frame = page_align((byte*) base);
509
504
 
510
505
        len = flst_get_len(base, mtr);
511
506
 
512
507
        fprintf(stderr,
513
508
                "FILE-BASED LIST:\n"
514
509
                "Base node in space %lu page %lu byte offset %lu; len %lu\n",
515
 
                (ulong) buf_frame_get_space_id(frame),
516
 
                (ulong) buf_frame_get_page_no(frame),
517
 
                (ulong) (base - frame), (ulong) len);
 
510
                (ulong) page_get_space_id(frame),
 
511
                (ulong) page_get_page_no(frame),
 
512
                (ulong) page_offset(base), (ulong) len);
518
513
}