📄 page0page.ic
字号:
/* out: number of user records */ page_t* page) /* in: index page */{ return(page_header_get_field(page, PAGE_N_HEAP) & 0x7fff);}/*****************************************************************Sets the number of records in the heap. */UNIV_INLINEvoidpage_dir_set_n_heap(/*================*/ page_t* page, /* in: index page */ ulint n_heap) /* in: number of records */{ ut_ad(n_heap < 0x8000); page_header_set_field(page, PAGE_N_HEAP, n_heap | (0x8000 & page_header_get_field(page, PAGE_N_HEAP)));}/*****************************************************************Gets pointer to nth directory slot. */UNIV_INLINEpage_dir_slot_t*page_dir_get_nth_slot(/*==================*/ /* out: pointer to dir slot */ page_t* page, /* in: index page */ ulint n) /* in: position */{ ut_ad(page_dir_get_n_slots(page) > n); return(page + UNIV_PAGE_SIZE - PAGE_DIR - (n + 1) * PAGE_DIR_SLOT_SIZE);} /******************************************************************Used to check the consistency of a record on a page. */UNIV_INLINEiboolpage_rec_check(/*===========*/ /* out: TRUE if succeed */ rec_t* rec) /* in: record */{ page_t* page; ut_a(rec); page = buf_frame_align(rec); ut_a(rec <= page_header_get_ptr(page, PAGE_HEAP_TOP)); ut_a(rec >= page + PAGE_DATA); return(TRUE);}/*******************************************************************Gets the record pointed to by a directory slot. */UNIV_INLINErec_t*page_dir_slot_get_rec(/*==================*/ /* out: pointer to record */ page_dir_slot_t* slot) /* in: directory slot */{ return(buf_frame_align(slot) + mach_read_from_2(slot));}/*******************************************************************This is used to set the record offset in a directory slot. */UNIV_INLINEvoidpage_dir_slot_set_rec(/*==================*/ page_dir_slot_t* slot, /* in: directory slot */ rec_t* rec) /* in: record on the page */{ ut_ad(page_rec_check(rec)); mach_write_to_2(slot, ut_align_offset(rec, UNIV_PAGE_SIZE));}/*******************************************************************Gets the number of records owned by a directory slot. */UNIV_INLINEulintpage_dir_slot_get_n_owned(/*======================*/ /* out: number of records */ page_dir_slot_t* slot) /* in: page directory slot */{ rec_t* rec = page_dir_slot_get_rec(slot); return(rec_get_n_owned(rec, page_rec_is_comp(rec)));}/*******************************************************************This is used to set the owned records field of a directory slot. */UNIV_INLINEvoidpage_dir_slot_set_n_owned(/*======================*/ page_dir_slot_t* slot, /* in: directory slot */ ulint n) /* in: number of records owned by the slot */{ rec_t* rec = page_dir_slot_get_rec(slot); rec_set_n_owned(rec, page_rec_is_comp(rec), n);}/****************************************************************Calculates the space reserved for directory slots of a given number ofrecords. The exact value is a fraction number n * PAGE_DIR_SLOT_SIZE /PAGE_DIR_SLOT_MIN_N_OWNED, and it is rounded upwards to an integer. */UNIV_INLINEulintpage_dir_calc_reserved_space(/*=========================*/ ulint n_recs) /* in: number of records */{ return((PAGE_DIR_SLOT_SIZE * n_recs + PAGE_DIR_SLOT_MIN_N_OWNED - 1) / PAGE_DIR_SLOT_MIN_N_OWNED);} /****************************************************************Gets the pointer to the next record on the page. */UNIV_INLINErec_t*page_rec_get_next(/*==============*/ /* out: pointer to next record */ rec_t* rec) /* in: pointer to record */{ ulint offs; page_t* page; ut_ad(page_rec_check(rec)); page = ut_align_down(rec, UNIV_PAGE_SIZE); offs = rec_get_next_offs(rec, page_is_comp(page)); if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) { fprintf(stderr,"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n""InnoDB: rec address %p, first buffer frame %p\n""InnoDB: buffer pool high end %p, buf fix count %lu\n", (ulong)offs, (ulong)(rec - page), rec, buf_pool->frame_zero, buf_pool->high_end, (ulong)buf_block_align(rec)->buf_fix_count); buf_page_print(page); ut_error; } if (UNIV_UNLIKELY(offs == 0)) { return(NULL); } return(page + offs);}/****************************************************************Sets the pointer to the next record on the page. */ UNIV_INLINEvoidpage_rec_set_next(/*==============*/ rec_t* rec, /* in: pointer to record, must not be page supremum */ rec_t* next) /* in: pointer to next record, must not be page infimum */{ page_t* page; ulint offs; ut_ad(page_rec_check(rec)); ut_ad(!page_rec_is_supremum(rec)); page = ut_align_down(rec, UNIV_PAGE_SIZE); if (next) { ut_ad(!page_rec_is_infimum(next)); ut_ad(page == ut_align_down(next, UNIV_PAGE_SIZE)); offs = (ulint) (next - page); } else { offs = 0; } rec_set_next_offs(rec, page_is_comp(page), offs);}/****************************************************************Gets the pointer to the previous record. */UNIV_INLINErec_t*page_rec_get_prev(/*==============*/ /* out: pointer to previous record */ rec_t* rec) /* in: pointer to record, must not be page infimum */{ page_dir_slot_t* slot; ulint slot_no; rec_t* rec2; rec_t* prev_rec = NULL; page_t* page; ut_ad(page_rec_check(rec)); page = ut_align_down(rec, UNIV_PAGE_SIZE); ut_ad(!page_rec_is_infimum(rec)); slot_no = page_dir_find_owner_slot(rec); ut_a(slot_no != 0); slot = page_dir_get_nth_slot(page, slot_no - 1); rec2 = page_dir_slot_get_rec(slot); while (rec != rec2) { prev_rec = rec2; rec2 = page_rec_get_next(rec2); } ut_a(prev_rec); return(prev_rec);}/*******************************************************************Looks for the record which owns the given record. */UNIV_INLINErec_t*page_rec_find_owner_rec(/*====================*/ /* out: the owner record */ rec_t* rec) /* in: the physical record */{ ut_ad(page_rec_check(rec)); if (page_rec_is_comp(rec)) { while (rec_get_n_owned(rec, TRUE) == 0) { rec = page_rec_get_next(rec); } } else { while (rec_get_n_owned(rec, FALSE) == 0) { rec = page_rec_get_next(rec); } } return(rec);}/****************************************************************Returns the sum of the sizes of the records in the record list, excludingthe infimum and supremum records. */UNIV_INLINEulintpage_get_data_size(/*===============*/ /* out: data in bytes */ page_t* page) /* in: index page */{ ulint ret; ret = (ulint)(page_header_get_field(page, PAGE_HEAP_TOP) - (page_is_comp(page) ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END) - page_header_get_field(page, PAGE_GARBAGE)); ut_ad(ret < UNIV_PAGE_SIZE); return(ret);}/*****************************************************************Calculates free space if a page is emptied. */UNIV_INLINEulintpage_get_free_space_of_empty(/*=========================*/ /* out: free space */ ulint comp) /* in: nonzero=compact page layout */{ if (UNIV_LIKELY(comp)) { return((ulint)(UNIV_PAGE_SIZE - PAGE_NEW_SUPREMUM_END - PAGE_DIR - 2 * PAGE_DIR_SLOT_SIZE)); } return((ulint)(UNIV_PAGE_SIZE - PAGE_OLD_SUPREMUM_END - PAGE_DIR - 2 * PAGE_DIR_SLOT_SIZE));}/****************************************************************Each user record on a page, and also the deleted user records in the heaptakes its size plus the fraction of the dir cell size /PAGE_DIR_SLOT_MIN_N_OWNED bytes for it. If the sum of these exceeds thevalue of page_get_free_space_of_empty, the insert is impossible, otherwiseit is allowed. This function returns the maximum combined size of recordswhich can be inserted on top of the record heap. */UNIV_INLINEulintpage_get_max_insert_size(/*=====================*/ /* out: maximum combined size for inserted records */ page_t* page, /* in: index page */ ulint n_recs) /* in: number of records */{ ulint occupied; ulint free_space; if (page_is_comp(page)) { occupied = page_header_get_field(page, PAGE_HEAP_TOP) - PAGE_NEW_SUPREMUM_END + page_dir_calc_reserved_space( n_recs + page_dir_get_n_heap(page) - 2); free_space = page_get_free_space_of_empty(TRUE); } else { occupied = page_header_get_field(page, PAGE_HEAP_TOP) - PAGE_OLD_SUPREMUM_END + page_dir_calc_reserved_space( n_recs + page_dir_get_n_heap(page) - 2); free_space = page_get_free_space_of_empty(FALSE); } /* Above the 'n_recs +' part reserves directory space for the new inserted records; the '- 2' excludes page infimum and supremum records */ if (occupied > free_space) { return(0); } return(free_space - occupied);}/****************************************************************Returns the maximum combined size of records which can be inserted on topof the record heap if a page is first reorganized. */UNIV_INLINEulintpage_get_max_insert_size_after_reorganize(/*======================================*/ /* out: maximum combined size for inserted records */ page_t* page, /* in: index page */ ulint n_recs) /* in: number of records */{ ulint occupied; ulint free_space; occupied = page_get_data_size(page) + page_dir_calc_reserved_space(n_recs + page_get_n_recs(page)); free_space = page_get_free_space_of_empty(page_is_comp(page)); if (occupied > free_space) { return(0); } return(free_space - occupied);}/****************************************************************Puts a record to free list. */UNIV_INLINEvoidpage_mem_free(/*==========*/ page_t* page, /* in: index page */ rec_t* rec, /* in: pointer to the (origin of) record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ rec_t* free; ulint garbage; ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec)); free = page_header_get_ptr(page, PAGE_FREE); page_rec_set_next(rec, free); page_header_set_ptr(page, PAGE_FREE, rec);#if 0 /* It's better not to destroy the user's data. */ /* Clear the data bytes of the deleted record in order to improve the compression ratio of the page and to make it easier to read page dumps in corruption reports. The extra bytes of the record cannot be cleared, because page_mem_alloc() needs them in order to determine the size of the deleted record. */ memset(rec, 0, rec_offs_data_size(offsets));#endif garbage = page_header_get_field(page, PAGE_GARBAGE); page_header_set_field(page, PAGE_GARBAGE, garbage + rec_offs_size(offsets));}#ifdef UNIV_MATERIALIZE#undef UNIV_INLINE#define UNIV_INLINE UNIV_INLINE_ORIGINAL#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -