~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/page0page.ic

  • 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:
9
9
#include "mach0data.h"
10
10
#include "rem0cmp.h"
11
11
#include "mtr0log.h"
12
 
#include "page0zip.h"
13
12
 
14
13
#ifdef UNIV_MATERIALIZE
15
14
#undef UNIV_INLINE
44
43
dulint
45
44
page_get_max_trx_id(
46
45
/*================*/
47
 
        const page_t*   page)   /* in: page */
 
46
        page_t* page)   /* in: page */
48
47
{
49
48
        ut_ad(page);
50
49
 
58
57
void
59
58
page_update_max_trx_id(
60
59
/*===================*/
61
 
        buf_block_t*    block,  /* in/out: page */
62
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
63
 
                                uncompressed part will be updated, or NULL */
64
 
        dulint          trx_id) /* in: transaction id */
 
60
        page_t* page,   /* in: page */
 
61
        dulint  trx_id) /* in: transaction id */
65
62
{
66
 
        ut_ad(block);
67
 
 
68
 
        if (ut_dulint_cmp(page_get_max_trx_id(buf_block_get_frame(block)),
69
 
                          trx_id) < 0) {
70
 
 
71
 
                page_set_max_trx_id(block, page_zip, trx_id);
 
63
        ut_ad(page);
 
64
 
 
65
        if (ut_dulint_cmp(page_get_max_trx_id(page), trx_id) < 0) {
 
66
 
 
67
                page_set_max_trx_id(page, trx_id);
72
68
        }
73
69
}
74
70
 
78
74
ulint
79
75
page_header_get_field(
80
76
/*==================*/
81
 
        const page_t*   page,   /* in: page */
82
 
        ulint           field)  /* in: PAGE_LEVEL, ... */
 
77
        page_t* page,   /* in: page */
 
78
        ulint   field)  /* in: PAGE_LEVEL, ... */
83
79
{
84
80
        ut_ad(page);
85
81
        ut_ad(field <= PAGE_INDEX_ID);
93
89
void
94
90
page_header_set_field(
95
91
/*==================*/
96
 
        page_t*         page,   /* in/out: page */
97
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
98
 
                                uncompressed part will be updated, or NULL */
99
 
        ulint           field,  /* in: PAGE_N_DIR_SLOTS, ... */
100
 
        ulint           val)    /* in: value */
 
92
        page_t* page,   /* in: page */
 
93
        ulint   field,  /* in: PAGE_LEVEL, ... */
 
94
        ulint   val)    /* in: value */
101
95
{
102
96
        ut_ad(page);
103
97
        ut_ad(field <= PAGE_N_RECS);
105
99
        ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < UNIV_PAGE_SIZE);
106
100
 
107
101
        mach_write_to_2(page + PAGE_HEADER + field, val);
108
 
        if (UNIV_LIKELY_NULL(page_zip)) {
109
 
                page_zip_write_header(page_zip,
110
 
                                      page + PAGE_HEADER + field, 2, NULL);
111
 
        }
112
102
}
113
103
 
114
104
/*****************************************************************
115
 
Returns the offset stored in the given header field. */
 
105
Returns the pointer stored in the given header field. */
116
106
UNIV_INLINE
117
 
ulint
118
 
page_header_get_offs(
119
 
/*=================*/
120
 
                                /* out: offset from the start of the page,
121
 
                                or 0 */
122
 
        const page_t*   page,   /* in: page */
123
 
        ulint           field)  /* in: PAGE_FREE, ... */
 
107
byte*
 
108
page_header_get_ptr(
 
109
/*================*/
 
110
                        /* out: pointer or NULL */
 
111
        page_t* page,   /* in: page */
 
112
        ulint   field)  /* in: PAGE_FREE, ... */
124
113
{
125
114
        ulint   offs;
126
115
 
133
122
 
134
123
        ut_ad((field != PAGE_HEAP_TOP) || offs);
135
124
 
136
 
        return(offs);
 
125
        if (offs == 0) {
 
126
 
 
127
                return(NULL);
 
128
        }
 
129
 
 
130
        return(page + offs);
137
131
}
138
132
 
139
133
/*****************************************************************
142
136
void
143
137
page_header_set_ptr(
144
138
/*================*/
145
 
        page_t*         page,   /* in: page */
146
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
147
 
                                uncompressed part will be updated, or NULL */
148
 
        ulint           field,  /* in: PAGE_FREE, ... */
149
 
        const byte*     ptr)    /* in: pointer or NULL*/
 
139
        page_t* page,   /* in: page */
 
140
        ulint   field,  /* in: PAGE_FREE, ... */
 
141
        byte*   ptr)    /* in: pointer or NULL*/
150
142
{
151
143
        ulint   offs;
152
144
 
163
155
 
164
156
        ut_ad((field != PAGE_HEAP_TOP) || offs);
165
157
 
166
 
        page_header_set_field(page, page_zip, field, offs);
 
158
        page_header_set_field(page, field, offs);
167
159
}
168
160
 
169
161
/*****************************************************************
173
165
void
174
166
page_header_reset_last_insert(
175
167
/*==========================*/
176
 
        page_t*         page,   /* in/out: page */
177
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
178
 
                                uncompressed part will be updated, or NULL */
179
 
        mtr_t*          mtr)    /* in: mtr */
 
168
        page_t* page,   /* in: page */
 
169
        mtr_t*  mtr)    /* in: mtr */
180
170
{
181
171
        ut_ad(page && mtr);
182
172
 
183
 
        if (UNIV_LIKELY_NULL(page_zip)) {
184
 
                mach_write_to_2(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0);
185
 
                page_zip_write_header(page_zip,
186
 
                                      page + (PAGE_HEADER + PAGE_LAST_INSERT),
187
 
                                      2, mtr);
188
 
        } else {
189
 
                mlog_write_ulint(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0,
190
 
                                 MLOG_2BYTES, mtr);
191
 
        }
 
173
        mlog_write_ulint(page + PAGE_HEADER + PAGE_LAST_INSERT, 0,
 
174
                         MLOG_2BYTES, mtr);
192
175
}
193
176
 
194
177
/****************************************************************
197
180
ulint
198
181
page_is_comp(
199
182
/*=========*/
200
 
                                /* out: nonzero if the page is in compact
201
 
                                format, zero if it is in old-style format */
202
 
        const page_t*   page)   /* in: index page */
 
183
                        /* out: nonzero if the page is in compact
 
184
                        format, zero if it is in old-style format */
 
185
        page_t* page)   /* in: index page */
203
186
{
204
187
        return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
205
188
                           0x8000));
217
200
        return(page_is_comp(page_align(rec)));
218
201
}
219
202
 
220
 
/*******************************************************************
221
 
Returns the heap number of a record. */
222
 
UNIV_INLINE
223
 
ulint
224
 
page_rec_get_heap_no(
225
 
/*=================*/
226
 
                                /* out: heap number */
227
 
        const rec_t*    rec)    /* in: the physical record */
228
 
{
229
 
        if (page_rec_is_comp(rec)) {
230
 
                return(rec_get_heap_no_new(rec));
231
 
        } else {
232
 
                return(rec_get_heap_no_old(rec));
233
 
        }
234
 
}
235
 
 
236
 
/****************************************************************
237
 
Determine whether the page is a B-tree leaf. */
238
 
UNIV_INLINE
239
 
ibool
240
 
page_is_leaf(
241
 
/*=========*/
242
 
                                /* out: TRUE if the page is a B-tree leaf */
243
 
        const page_t*   page)   /* in: page */
244
 
{
245
 
        return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
246
 
}
247
 
 
248
203
/****************************************************************
249
204
Gets the first record on the page. */
250
205
UNIV_INLINE
398
353
                                /* out: 1, 0, -1, if dtuple is greater, equal,
399
354
                                less than rec, respectively, when only the
400
355
                                common first fields are compared */
401
 
        const dtuple_t* dtuple, /* in: data tuple */
402
 
        const rec_t*    rec,    /* in: physical record on a page; may also
 
356
        dtuple_t*       dtuple, /* in: data tuple */
 
357
        rec_t*          rec,    /* in: physical record on a page; may also
403
358
                                be page infimum or supremum, in which case
404
359
                                matched-parameter values below are not
405
360
                                affected */
435
390
}
436
391
 
437
392
/*****************************************************************
438
 
Gets the page number. */
439
 
UNIV_INLINE
440
 
ulint
441
 
page_get_page_no(
442
 
/*=============*/
443
 
                                /* out: page number */
444
 
        const page_t*   page)   /* in: page */
445
 
{
446
 
        ut_ad(page == page_align((page_t*) page));
447
 
        return(mach_read_from_4(page + FIL_PAGE_OFFSET));
448
 
}
449
 
 
450
 
/*****************************************************************
451
 
Gets the tablespace identifier. */
452
 
UNIV_INLINE
453
 
ulint
454
 
page_get_space_id(
455
 
/*==============*/
456
 
                                /* out: space id */
457
 
        const page_t*   page)   /* in: page */
458
 
{
459
 
        ut_ad(page == page_align((page_t*) page));
460
 
        return(mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
461
 
}
462
 
 
463
 
/*****************************************************************
464
393
Gets the number of user records on page (infimum and supremum records
465
394
are not user records). */
466
395
UNIV_INLINE
467
396
ulint
468
397
page_get_n_recs(
469
398
/*============*/
470
 
                                /* out: number of user records */
471
 
        const page_t*   page)   /* in: index page */
 
399
                        /* out: number of user records */
 
400
        page_t* page)   /* in: index page */
472
401
{
473
402
        return(page_header_get_field(page, PAGE_N_RECS));
474
403
}
479
408
ulint
480
409
page_dir_get_n_slots(
481
410
/*=================*/
482
 
                                /* out: number of slots */
483
 
        const page_t*   page)   /* in: index page */
 
411
                        /* out: number of slots */
 
412
        page_t* page)   /* in: index page */
484
413
{
485
414
        return(page_header_get_field(page, PAGE_N_DIR_SLOTS));
486
415
}
490
419
void
491
420
page_dir_set_n_slots(
492
421
/*=================*/
493
 
        page_t*         page,   /* in/out: page */
494
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
495
 
                                uncompressed part will be updated, or NULL */
496
 
        ulint           n_slots)/* in: number of slots */
 
422
                        /* out: number of slots */
 
423
        page_t* page,   /* in: index page */
 
424
        ulint   n_slots)/* in: number of slots */
497
425
{
498
 
        page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots);
 
426
        page_header_set_field(page, PAGE_N_DIR_SLOTS, n_slots);
499
427
}
500
428
 
501
429
/*****************************************************************
504
432
ulint
505
433
page_dir_get_n_heap(
506
434
/*================*/
507
 
                                /* out: number of user records */
508
 
        const page_t*   page)   /* in: index page */
 
435
                        /* out: number of user records */
 
436
        page_t* page)   /* in: index page */
509
437
{
510
438
        return(page_header_get_field(page, PAGE_N_HEAP) & 0x7fff);
511
439
}
516
444
void
517
445
page_dir_set_n_heap(
518
446
/*================*/
519
 
        page_t*         page,   /* in/out: index page */
520
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose
521
 
                                uncompressed part will be updated, or NULL.
522
 
                                Note that the size of the dense page directory
523
 
                                in the compressed page trailer is
524
 
                                n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
525
 
        ulint           n_heap) /* in: number of records */
 
447
        page_t* page,   /* in: index page */
 
448
        ulint   n_heap) /* in: number of records */
526
449
{
527
450
        ut_ad(n_heap < 0x8000);
528
 
        ut_ad(!page_zip || n_heap
529
 
              == (page_header_get_field(page, PAGE_N_HEAP) & 0x7fff) + 1);
530
451
 
531
 
        page_header_set_field(page, page_zip, PAGE_N_HEAP, n_heap
 
452
        page_header_set_field(page, PAGE_N_HEAP, n_heap
532
453
                              | (0x8000
533
454
                                 & page_header_get_field(page, PAGE_N_HEAP)));
534
455
}
535
456
 
536
 
#ifdef UNIV_DEBUG
537
457
/*****************************************************************
538
458
Gets pointer to nth directory slot. */
539
459
UNIV_INLINE
540
460
page_dir_slot_t*
541
461
page_dir_get_nth_slot(
542
462
/*==================*/
543
 
                                /* out: pointer to dir slot */
544
 
        const page_t*   page,   /* in: index page */
545
 
        ulint           n)      /* in: position */
 
463
                        /* out: pointer to dir slot */
 
464
        page_t* page,   /* in: index page */
 
465
        ulint   n)      /* in: position */
546
466
{
547
467
        ut_ad(page_dir_get_n_slots(page) > n);
548
468
 
549
 
        return((page_dir_slot_t*)
550
 
               page + UNIV_PAGE_SIZE - PAGE_DIR
 
469
        return(page + UNIV_PAGE_SIZE - PAGE_DIR
551
470
               - (n + 1) * PAGE_DIR_SLOT_SIZE);
552
471
}
553
 
#endif /* UNIV_DEBUG */
554
472
 
555
473
/******************************************************************
556
474
Used to check the consistency of a record on a page. */
558
476
ibool
559
477
page_rec_check(
560
478
/*===========*/
561
 
                                /* out: TRUE if succeed */
562
 
        const rec_t*    rec)    /* in: record */
 
479
                        /* out: TRUE if succeed */
 
480
        rec_t*  rec)    /* in: record */
563
481
{
564
 
        const page_t*   page = page_align(rec);
 
482
        page_t* page;
565
483
 
566
484
        ut_a(rec);
567
485
 
568
 
        ut_a(page_offset(rec) <= page_header_get_field(page, PAGE_HEAP_TOP));
569
 
        ut_a(page_offset(rec) >= PAGE_DATA);
 
486
        page = buf_frame_align(rec);
 
487
 
 
488
        ut_a(rec <= page_header_get_ptr(page, PAGE_HEAP_TOP));
 
489
        ut_a(rec >= page + PAGE_DATA);
570
490
 
571
491
        return(TRUE);
572
492
}
574
494
/*******************************************************************
575
495
Gets the record pointed to by a directory slot. */
576
496
UNIV_INLINE
577
 
const rec_t*
 
497
rec_t*
578
498
page_dir_slot_get_rec(
579
499
/*==================*/
580
500
                                        /* out: pointer to record */
581
 
        const page_dir_slot_t*  slot)   /* in: directory slot */
 
501
        page_dir_slot_t*        slot)   /* in: directory slot */
582
502
{
583
 
        return(page_align(slot) + mach_read_from_2(slot));
 
503
        return(buf_frame_align(slot) + mach_read_from_2(slot));
584
504
}
585
505
 
586
506
/*******************************************************************
604
524
page_dir_slot_get_n_owned(
605
525
/*======================*/
606
526
                                        /* out: number of records */
607
 
        const page_dir_slot_t*  slot)   /* in: page directory slot */
 
527
        page_dir_slot_t*        slot)   /* in: page directory slot */
608
528
{
609
 
        const rec_t*    rec     = page_dir_slot_get_rec(slot);
610
 
        if (page_rec_is_comp(slot)) {
611
 
                return(rec_get_n_owned_new(rec));
612
 
        } else {
613
 
                return(rec_get_n_owned_old(rec));
614
 
        }
 
529
        rec_t*  rec     = page_dir_slot_get_rec(slot);
 
530
        return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
615
531
}
616
532
 
617
533
/*******************************************************************
620
536
void
621
537
page_dir_slot_set_n_owned(
622
538
/*======================*/
623
 
        page_dir_slot_t*slot,   /* in/out: directory slot */
624
 
        page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
625
 
        ulint           n)      /* in: number of records owned by the slot */
 
539
        page_dir_slot_t*        slot,   /* in: directory slot */
 
540
        ulint                   n)      /* in: number of records owned
 
541
                                        by the slot */
626
542
{
627
 
        rec_t*  rec     = (rec_t*) page_dir_slot_get_rec(slot);
628
 
        if (page_rec_is_comp(slot)) {
629
 
                rec_set_n_owned_new(rec, page_zip, n);
630
 
        } else {
631
 
                ut_ad(!page_zip);
632
 
                rec_set_n_owned_old(rec, n);
633
 
        }
 
543
        rec_t*  rec     = page_dir_slot_get_rec(slot);
 
544
        rec_set_n_owned(rec, page_rec_is_comp(rec), n);
634
545
}
635
546
 
636
547
/****************************************************************
650
561
/****************************************************************
651
562
Gets the pointer to the next record on the page. */
652
563
UNIV_INLINE
653
 
const rec_t*
654
 
page_rec_get_next_low(
655
 
/*==================*/
656
 
                                /* out: pointer to next record */
657
 
        const rec_t*    rec,    /* in: pointer to record */
658
 
        ulint           comp)   /* in: nonzero=compact page layout */
 
564
rec_t*
 
565
page_rec_get_next(
 
566
/*==============*/
 
567
                        /* out: pointer to next record */
 
568
        rec_t*  rec)    /* in: pointer to record */
659
569
{
660
 
        ulint           offs;
661
 
        const page_t*   page;
 
570
        ulint   offs;
 
571
        page_t* page;
662
572
 
663
573
        ut_ad(page_rec_check(rec));
664
574
 
665
575
        page = page_align(rec);
666
576
 
667
 
        offs = rec_get_next_offs(rec, comp);
 
577
        offs = rec_get_next_offs(rec, page_is_comp(page));
668
578
 
669
579
        if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
670
580
                fprintf(stderr,
671
581
                        "InnoDB: Next record offset is nonsensical %lu"
672
582
                        " in record at offset %lu\n"
673
 
                        "InnoDB: rec address %p, space id %lu, page %lu\n",
674
 
                        (ulong)offs, (ulong) page_offset(rec),
675
 
                        (void*) rec,
676
 
                        (ulong) page_get_space_id(page),
677
 
                        (ulong) page_get_page_no(page));
678
 
                buf_page_print(page, 0);
 
583
                        "InnoDB: rec address %p, first buffer frame %p\n"
 
584
                        "InnoDB: buffer pool high end %p, buf fix count %lu\n",
 
585
                        (ulong)offs, (ulong)(rec - page),
 
586
                        (void*) rec, (void*) buf_pool->frame_zero,
 
587
                        (void*) buf_pool->high_end,
 
588
                        (ulong) buf_block_align(rec)->buf_fix_count);
 
589
                buf_page_print(page);
679
590
 
680
591
                ut_error;
681
592
        }
689
600
}
690
601
 
691
602
/****************************************************************
692
 
Gets the pointer to the next record on the page. */
693
 
UNIV_INLINE
694
 
rec_t*
695
 
page_rec_get_next(
696
 
/*==============*/
697
 
                        /* out: pointer to next record */
698
 
        rec_t*  rec)    /* in: pointer to record */
699
 
{
700
 
        return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
701
 
}
702
 
 
703
 
/****************************************************************
704
 
Gets the pointer to the next record on the page. */
705
 
UNIV_INLINE
706
 
const rec_t*
707
 
page_rec_get_next_const(
708
 
/*====================*/
709
 
                                /* out: pointer to next record */
710
 
        const rec_t*    rec)    /* in: pointer to record */
711
 
{
712
 
        return(page_rec_get_next_low(rec, page_rec_is_comp(rec)));
713
 
}
714
 
 
715
 
/****************************************************************
716
603
Sets the pointer to the next record on the page. */
717
604
UNIV_INLINE
718
605
void
719
606
page_rec_set_next(
720
607
/*==============*/
721
 
        rec_t*  rec,            /* in: pointer to record,
722
 
                                must not be page supremum */
723
 
        rec_t*  next)           /* in: pointer to next record,
724
 
                                must not be page infimum */
 
608
        rec_t*  rec,    /* in: pointer to record, must not be page supremum */
 
609
        rec_t*  next)   /* in: pointer to next record, must not be page
 
610
                        infimum */
725
611
{
 
612
        page_t* page;
726
613
        ulint   offs;
727
614
 
728
615
        ut_ad(page_rec_check(rec));
729
616
        ut_ad(!page_rec_is_supremum(rec));
730
 
        ut_ad(rec != next);
731
 
 
732
 
        ut_ad(!next || !page_rec_is_infimum(next));
733
 
        ut_ad(!next || page_align(rec) == page_align(next));
734
 
 
735
 
        if (UNIV_LIKELY(next != NULL)) {
736
 
                offs = page_offset(next);
 
617
        page = page_align(rec);
 
618
 
 
619
        if (next) {
 
620
                ut_ad(!page_rec_is_infimum(next));
 
621
                ut_ad(page == page_align(next));
 
622
                offs = (ulint) (next - page);
737
623
        } else {
738
624
                offs = 0;
739
625
        }
740
626
 
741
 
        if (page_rec_is_comp(rec)) {
742
 
                rec_set_next_offs_new(rec, offs);
743
 
        } else {
744
 
                rec_set_next_offs_old(rec, offs);
745
 
        }
 
627
        rec_set_next_offs(rec, page_is_comp(page), offs);
746
628
}
747
629
 
748
630
/****************************************************************
749
631
Gets the pointer to the previous record. */
750
632
UNIV_INLINE
751
 
const rec_t*
752
 
page_rec_get_prev_const(
753
 
/*====================*/
754
 
                                /* out: pointer to previous record */
755
 
        const rec_t*    rec)    /* in: pointer to record, must not be page
756
 
                                infimum */
 
633
rec_t*
 
634
page_rec_get_prev(
 
635
/*==============*/
 
636
                        /* out: pointer to previous record */
 
637
        rec_t*  rec)    /* in: pointer to record, must not be page
 
638
                        infimum */
757
639
{
758
 
        const page_dir_slot_t*  slot;
 
640
        page_dir_slot_t*        slot;
759
641
        ulint                   slot_no;
760
 
        const rec_t*            rec2;
761
 
        const rec_t*            prev_rec = NULL;
762
 
        const page_t*           page;
 
642
        rec_t*                  rec2;
 
643
        rec_t*                  prev_rec = NULL;
 
644
        page_t*                 page;
763
645
 
764
646
        ut_ad(page_rec_check(rec));
765
647
 
775
657
 
776
658
        rec2 = page_dir_slot_get_rec(slot);
777
659
 
778
 
        if (page_is_comp(page)) {
779
 
                while (rec != rec2) {
780
 
                        prev_rec = rec2;
781
 
                        rec2 = page_rec_get_next_low(rec2, TRUE);
782
 
                }
783
 
        } else {
784
 
                while (rec != rec2) {
785
 
                        prev_rec = rec2;
786
 
                        rec2 = page_rec_get_next_low(rec2, FALSE);
787
 
                }
 
660
        while (rec != rec2) {
 
661
                prev_rec = rec2;
 
662
                rec2 = page_rec_get_next(rec2);
788
663
        }
789
664
 
790
665
        ut_a(prev_rec);
792
667
        return(prev_rec);
793
668
}
794
669
 
795
 
/****************************************************************
796
 
Gets the pointer to the previous record. */
797
 
UNIV_INLINE
798
 
rec_t*
799
 
page_rec_get_prev(
800
 
/*==============*/
801
 
                        /* out: pointer to previous record */
802
 
        rec_t*  rec)    /* in: pointer to record, must not be page
803
 
                        infimum */
804
 
{
805
 
        return((rec_t*) page_rec_get_prev_const(rec));
806
 
}
807
 
 
808
670
/*******************************************************************
809
671
Looks for the record which owns the given record. */
810
672
UNIV_INLINE
817
679
        ut_ad(page_rec_check(rec));
818
680
 
819
681
        if (page_rec_is_comp(rec)) {
820
 
                while (rec_get_n_owned_new(rec) == 0) {
 
682
                while (rec_get_n_owned(rec, TRUE) == 0) {
821
683
                        rec = page_rec_get_next(rec);
822
684
                }
823
685
        } else {
824
 
                while (rec_get_n_owned_old(rec) == 0) {
 
686
                while (rec_get_n_owned(rec, FALSE) == 0) {
825
687
                        rec = page_rec_get_next(rec);
826
688
                }
827
689
        }
829
691
        return(rec);
830
692
}
831
693
 
832
 
/**************************************************************
833
 
Returns the base extra size of a physical record.  This is the
834
 
size of the fixed header, independent of the record size. */
835
 
UNIV_INLINE
836
 
ulint
837
 
page_rec_get_base_extra_size(
838
 
/*=========================*/
839
 
                                /* out: REC_N_NEW_EXTRA_BYTES
840
 
                                or REC_N_OLD_EXTRA_BYTES */
841
 
        const rec_t*    rec)    /* in: physical record */
842
 
{
843
 
#if REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES
844
 
# error "REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES"
845
 
#endif
846
 
        return(REC_N_NEW_EXTRA_BYTES + (ulint) !page_rec_is_comp(rec));
847
 
}
848
 
 
849
694
/****************************************************************
850
695
Returns the sum of the sizes of the records in the record list, excluding
851
696
the infimum and supremum records. */
853
698
ulint
854
699
page_get_data_size(
855
700
/*===============*/
856
 
                                /* out: data in bytes */
857
 
        const page_t*   page)   /* in: index page */
 
701
                        /* out: data in bytes */
 
702
        page_t* page)   /* in: index page */
858
703
{
859
704
        ulint   ret;
860
705
 
869
714
        return(ret);
870
715
}
871
716
 
872
 
 
873
 
/****************************************************************
874
 
Allocates a block of memory from the free list of an index page. */
875
 
UNIV_INTERN
876
 
void
877
 
page_mem_alloc_free(
878
 
/*================*/
879
 
        page_t*         page,   /* in/out: index page */
880
 
        page_zip_des_t* page_zip,/* in/out: compressed page with enough
881
 
                                space available for inserting the record,
882
 
                                or NULL */
883
 
        rec_t*          next_rec,/* in: pointer to the new head of the
884
 
                                free record list */
885
 
        ulint           need)   /* in: number of bytes allocated */
886
 
{
887
 
        ulint           garbage;
888
 
 
889
 
#ifdef UNIV_DEBUG
890
 
        const rec_t*    old_rec = page_header_get_ptr(page, PAGE_FREE);
891
 
        ulint           next_offs;
892
 
 
893
 
        ut_ad(old_rec);
894
 
        next_offs = rec_get_next_offs(old_rec, page_is_comp(page));
895
 
        ut_ad(next_rec == (next_offs ? page + next_offs : NULL));
896
 
#endif
897
 
 
898
 
        page_header_set_ptr(page, page_zip, PAGE_FREE, next_rec);
899
 
 
900
 
        garbage = page_header_get_field(page, PAGE_GARBAGE);
901
 
        ut_ad(garbage >= need);
902
 
 
903
 
        page_header_set_field(page, page_zip, PAGE_GARBAGE, garbage - need);
904
 
}
905
 
 
906
717
/*****************************************************************
907
718
Calculates free space if a page is emptied. */
908
719
UNIV_INLINE
936
747
ulint
937
748
page_get_max_insert_size(
938
749
/*=====================*/
939
 
                                /* out: maximum combined size for
940
 
                                inserted records */
941
 
        const page_t*   page,   /* in: index page */
942
 
        ulint           n_recs) /* in: number of records */
 
750
                        /* out: maximum combined size for inserted records */
 
751
        page_t* page,   /* in: index page */
 
752
        ulint   n_recs) /* in: number of records */
943
753
{
944
754
        ulint   occupied;
945
755
        ulint   free_space;
979
789
ulint
980
790
page_get_max_insert_size_after_reorganize(
981
791
/*======================================*/
982
 
                                /* out: maximum combined size for
983
 
                                inserted records */
984
 
        const page_t*   page,   /* in: index page */
985
 
        ulint           n_recs) /* in: number of records */
 
792
                        /* out: maximum combined size for inserted records */
 
793
        page_t* page,   /* in: index page */
 
794
        ulint   n_recs) /* in: number of records */
986
795
{
987
796
        ulint   occupied;
988
797
        ulint   free_space;
1006
815
void
1007
816
page_mem_free(
1008
817
/*==========*/
1009
 
        page_t*         page,   /* in/out: index page */
1010
 
        page_zip_des_t* page_zip,/* in/out: compressed page with at least
1011
 
                                6 bytes available, or NULL */
 
818
        page_t*         page,   /* in: index page */
1012
819
        rec_t*          rec,    /* in: pointer to the (origin of) record */
1013
 
        dict_index_t*   index,  /* in: index of rec */
1014
820
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
1015
821
{
1016
822
        rec_t*          free;
1017
823
        ulint           garbage;
1018
824
 
1019
 
        ut_ad(rec_offs_validate(rec, index, offsets));
 
825
        ut_ad(rec_offs_validate(rec, NULL, offsets));
 
826
        ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
1020
827
        free = page_header_get_ptr(page, PAGE_FREE);
1021
828
 
1022
829
        page_rec_set_next(rec, free);
1023
 
        page_header_set_ptr(page, page_zip, PAGE_FREE, rec);
 
830
        page_header_set_ptr(page, PAGE_FREE, rec);
 
831
 
 
832
#if 0   /* It's better not to destroy the user's data. */
 
833
 
 
834
        /* Clear the data bytes of the deleted record in order to improve
 
835
        the compression ratio of the page and to make it easier to read
 
836
        page dumps in corruption reports.  The extra bytes of the record
 
837
        cannot be cleared, because page_mem_alloc() needs them in order
 
838
        to determine the size of the deleted record. */
 
839
        memset(rec, 0, rec_offs_data_size(offsets));
 
840
#endif
1024
841
 
1025
842
        garbage = page_header_get_field(page, PAGE_GARBAGE);
1026
843
 
1027
 
        page_header_set_field(page, page_zip, PAGE_GARBAGE,
 
844
        page_header_set_field(page, PAGE_GARBAGE,
1028
845
                              garbage + rec_offs_size(offsets));
1029
 
 
1030
 
        if (UNIV_LIKELY_NULL(page_zip)) {
1031
 
                page_zip_dir_delete(page_zip, rec, index, offsets, free);
1032
 
        } else {
1033
 
                page_header_set_field(page, page_zip, PAGE_N_RECS,
1034
 
                                      page_get_n_recs(page) - 1);
1035
 
        }
1036
846
}
1037
847
 
1038
848
#ifdef UNIV_MATERIALIZE