⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 page0cur.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	rec_set_n_owned(insert_rec, comp, 0);	rec_set_heap_no(insert_rec, comp, heap_no);	/* 6. Update the last insertion info in page header */		last_insert = page_header_get_ptr(page, PAGE_LAST_INSERT);	ut_ad(!last_insert || !comp		|| rec_get_node_ptr_flag(last_insert)		== rec_get_node_ptr_flag(insert_rec));	if (last_insert == NULL) {	    	page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);	    	page_header_set_field(page, PAGE_N_DIRECTION, 0);	} else if ((last_insert == current_rec)	    && (page_header_get_field(page, PAGE_DIRECTION) != PAGE_LEFT)) {	    	page_header_set_field(page, PAGE_DIRECTION, PAGE_RIGHT);	    	page_header_set_field(page, PAGE_N_DIRECTION,			page_header_get_field(page, PAGE_N_DIRECTION) + 1);	} else if ((page_rec_get_next(insert_rec) == last_insert)	    && (page_header_get_field(page, PAGE_DIRECTION) != PAGE_RIGHT)) {	    	page_header_set_field(page, PAGE_DIRECTION, PAGE_LEFT);	    	page_header_set_field(page, PAGE_N_DIRECTION,			page_header_get_field(page, PAGE_N_DIRECTION) + 1);	} else {	    	page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);	    	page_header_set_field(page, PAGE_N_DIRECTION, 0);	}		page_header_set_ptr(page, PAGE_LAST_INSERT, insert_rec);	/* 7. It remains to update the owner record. */				owner_rec = page_rec_find_owner_rec(insert_rec);	n_owned = rec_get_n_owned(owner_rec, comp);	rec_set_n_owned(owner_rec, comp, n_owned + 1);	/* 8. Now we have incremented the n_owned field of the owner	record. If the number exceeds PAGE_DIR_SLOT_MAX_N_OWNED,	we have to split the corresponding directory slot in two. */	if (n_owned == PAGE_DIR_SLOT_MAX_N_OWNED) {		owner_slot = page_dir_find_owner_slot(owner_rec);		page_dir_split_slot(page, owner_slot);	}	/* 9. Write log record of the insert */	page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,				index, mtr);		if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	return(insert_rec);}/**************************************************************Writes a log record of copying a record list end to a new created page. */UNIV_INLINEbyte*page_copy_rec_list_to_created_page_write_log(/*=========================================*/				/* out: 4-byte field where to				write the log data length */	page_t*		page,	/* in: index page */	dict_index_t*	index,	/* in: record descriptor */	mtr_t*		mtr)	/* in: mtr */{	byte*	log_ptr;	ut_ad(!!page_is_comp(page) == index->table->comp);	log_ptr = mlog_open_and_write_index(mtr, page, index,			page_is_comp(page)			? MLOG_COMP_LIST_END_COPY_CREATED			: MLOG_LIST_END_COPY_CREATED, 4);	ut_a(log_ptr);	mlog_close(mtr, log_ptr + 4);	return(log_ptr);}/**************************************************************Parses a log record of copying a record list end to a new created page. */byte*page_parse_copy_rec_list_to_created_page(/*=====================================*/				/* out: end of log record or NULL */	byte*		ptr,	/* in: buffer */	byte*		end_ptr,/* in: buffer end */	dict_index_t*	index,	/* in: record descriptor */	page_t*		page,	/* in: page or NULL */	mtr_t*		mtr)	/* in: mtr or NULL */{	byte*	rec_end;	ulint	log_data_len;		if (ptr + 4 > end_ptr) {		return(NULL);	}	log_data_len = mach_read_from_4(ptr);	ptr += 4;	rec_end = ptr + log_data_len;	if (rec_end > end_ptr) {		return(NULL);	}	if (!page) {		return(rec_end);	}	while (ptr < rec_end) {		ptr = page_cur_parse_insert_rec(TRUE, ptr, end_ptr,							index, page, mtr);	}	ut_a(ptr == rec_end);		page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);	page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);	page_header_set_field(page, PAGE_N_DIRECTION, 0);	return(rec_end);	}/*****************************************************************Copies records from page to a newly created page, from a given record onward,including that record. Infimum and supremum records are not copied. */voidpage_copy_rec_list_end_to_created_page(/*===================================*/	page_t*		new_page,	/* in: index page to copy to */	page_t*		page,		/* in: index page */	rec_t*		rec,		/* in: first record to copy */	dict_index_t*	index,		/* in: record descriptor */	mtr_t*		mtr)		/* in: mtr */{	page_dir_slot_t* slot = 0; /* remove warning */	byte*	heap_top;	rec_t*	insert_rec = 0; /* remove warning */	rec_t*	prev_rec;	ulint	count;	ulint	n_recs;	ulint	slot_index;	ulint	rec_size;	ulint	log_mode;	byte*	log_ptr;	ulint	log_data_len;	ulint		comp		= page_is_comp(page);	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;		ut_ad(page_dir_get_n_heap(new_page) == 2);	ut_ad(page != new_page);	ut_ad(comp == page_is_comp(new_page));		if (rec == page_get_infimum_rec(page)) {		rec = page_rec_get_next(rec);	}	if (rec == page_get_supremum_rec(page)) {		return;	}	#ifdef UNIV_DEBUG	/* To pass the debug tests we have to set these dummy values	in the debug version */	page_dir_set_n_slots(new_page, UNIV_PAGE_SIZE / 2);	page_header_set_ptr(new_page, PAGE_HEAP_TOP,					new_page + UNIV_PAGE_SIZE - 1);#endif	log_ptr = page_copy_rec_list_to_created_page_write_log(new_page,								index, mtr);	log_data_len = dyn_array_get_data_size(&(mtr->log));	/* Individual inserts are logged in a shorter form */	log_mode = mtr_set_log_mode(mtr, MTR_LOG_SHORT_INSERTS);		prev_rec = page_get_infimum_rec(new_page);	if (comp) {		heap_top = new_page + PAGE_NEW_SUPREMUM_END;	} else {		heap_top = new_page + PAGE_OLD_SUPREMUM_END;	}	count = 0;	slot_index = 0;	n_recs = 0;	/* should be do ... until, comment by Jani */	while (rec != page_get_supremum_rec(page)) {		offsets = rec_get_offsets(rec, index, offsets,					ULINT_UNDEFINED, &heap);		insert_rec = rec_copy(heap_top, rec, offsets);		rec_set_next_offs(prev_rec, comp, insert_rec - new_page);		rec_set_n_owned(insert_rec, comp, 0);		rec_set_heap_no(insert_rec, comp, 2 + n_recs);		rec_size = rec_offs_size(offsets);		heap_top = heap_top + rec_size;				ut_ad(heap_top < new_page + UNIV_PAGE_SIZE);		count++;		n_recs++;		if (count == (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2) {			slot_index++;			slot = page_dir_get_nth_slot(new_page, slot_index);			page_dir_slot_set_rec(slot, insert_rec);			page_dir_slot_set_n_owned(slot, count);			count = 0;		}		 		page_cur_insert_rec_write_log(insert_rec, rec_size, prev_rec,								index, mtr);		prev_rec = insert_rec;		rec = page_rec_get_next(rec);	}	if ((slot_index > 0) && (count + 1				+ (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2			     	 <= PAGE_DIR_SLOT_MAX_N_OWNED)) {		/* We can merge the two last dir slots. This operation is		here to make this function imitate exactly the equivalent		task made using page_cur_insert_rec, which we use in database		recovery to reproduce the task performed by this function.		To be able to check the correctness of recovery, it is good		that it imitates exactly. */		count += (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2;				page_dir_slot_set_n_owned(slot, 0);		slot_index--;	}	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len;	ut_a(log_data_len < 100 * UNIV_PAGE_SIZE);	mach_write_to_4(log_ptr, log_data_len);		rec_set_next_offs(insert_rec, comp,				comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM);	slot = page_dir_get_nth_slot(new_page, 1 + slot_index);	page_dir_slot_set_rec(slot, page_get_supremum_rec(new_page));	page_dir_slot_set_n_owned(slot, count + 1);	page_dir_set_n_slots(new_page, 2 + slot_index);	page_header_set_ptr(new_page, PAGE_HEAP_TOP, heap_top);	page_dir_set_n_heap(new_page, 2 + n_recs);	page_header_set_field(new_page, PAGE_N_RECS, n_recs);		page_header_set_ptr(new_page, PAGE_LAST_INSERT, NULL);	page_header_set_field(new_page, PAGE_DIRECTION, PAGE_NO_DIRECTION);	page_header_set_field(new_page, PAGE_N_DIRECTION, 0);	/* Restore the log mode */	mtr_set_log_mode(mtr, log_mode);}/***************************************************************Writes log record of a record delete on a page. */UNIV_INLINEvoidpage_cur_delete_rec_write_log(/*==========================*/	rec_t*		rec,	/* in: record to be deleted */	dict_index_t*	index,	/* in: record descriptor */	mtr_t*		mtr)	/* in: mini-transaction handle */{	byte*	log_ptr;	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);	log_ptr = mlog_open_and_write_index(mtr, rec, index,			page_rec_is_comp(rec)			? MLOG_COMP_REC_DELETE			: MLOG_REC_DELETE, 2);	if (!log_ptr) {		/* Logging in mtr is switched off during crash recovery:		in that case mlog_open returns NULL */		return;	}	/* Write the cursor rec offset as a 2-byte ulint */	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));	mlog_close(mtr, log_ptr + 2);}	/***************************************************************Parses log record of a record delete on a page. */byte*page_cur_parse_delete_rec(/*======================*/				/* out: pointer to record end or NULL */	byte*		ptr,	/* in: buffer */	byte*		end_ptr,/* in: buffer end */	dict_index_t*	index,	/* in: record descriptor */	page_t*		page,	/* in: page or NULL */	mtr_t*		mtr)	/* in: mtr or NULL */{	ulint		offset;	page_cur_t	cursor;		if (end_ptr < ptr + 2) {		return(NULL);	}	/* Read the cursor rec offset as a 2-byte ulint */	offset = mach_read_from_2(ptr);	ptr += 2;	ut_a(offset <= UNIV_PAGE_SIZE);	if (page) {		mem_heap_t*	heap		= NULL;		ulint		offsets_[REC_OFFS_NORMAL_SIZE];		rec_t*		rec		= page + offset;		*offsets_ = (sizeof offsets_) / sizeof *offsets_;		page_cur_position(rec, &cursor);		page_cur_delete_rec(&cursor, index,				rec_get_offsets(rec, index, offsets_,				ULINT_UNDEFINED, &heap), mtr);		if (UNIV_LIKELY_NULL(heap)) {			mem_heap_free(heap);		}	}	return(ptr);}	/***************************************************************Deletes a record at the page cursor. The cursor is moved to the nextrecord after the deleted one. */voidpage_cur_delete_rec(/*================*/	page_cur_t*  	cursor,	/* in: a page cursor */	dict_index_t*	index,	/* in: record descriptor */	const ulint*	offsets,/* in: rec_get_offsets(cursor->rec, index) */	mtr_t*		mtr)	/* in: mini-transaction handle */{	page_dir_slot_t* cur_dir_slot;	page_dir_slot_t* prev_slot;	page_t*		page;	rec_t*		current_rec;	rec_t*		prev_rec	= NULL;	rec_t*		next_rec;	ulint		cur_slot_no;	ulint		cur_n_owned;	rec_t*		rec;		ut_ad(cursor && mtr);		page = page_cur_get_page(cursor);	current_rec = cursor->rec;	ut_ad(rec_offs_validate(current_rec, index, offsets));	ut_ad(!!page_is_comp(page) == index->table->comp);	/* The record must not be the supremum or infimum record. */	ut_ad(current_rec != page_get_supremum_rec(page));		ut_ad(current_rec != page_get_infimum_rec(page));			/* Save to local variables some data associated with current_rec */	cur_slot_no = page_dir_find_owner_slot(current_rec);	cur_dir_slot = page_dir_get_nth_slot(page, cur_slot_no);	cur_n_owned = page_dir_slot_get_n_owned(cur_dir_slot);	/* 0. Write the log record */	page_cur_delete_rec_write_log(current_rec, index, mtr);	/* 1. Reset the last insert info in the page header and increment	the modify clock for the frame */	page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);	/* The page gets invalid for optimistic searches: increment the	frame modify clock */	buf_frame_modify_clock_inc(page);		/* 2. Find the next and the previous record. Note that the cursor is	left at the next record. */	ut_ad(cur_slot_no > 0);	prev_slot = page_dir_get_nth_slot(page, cur_slot_no - 1);		rec = page_dir_slot_get_rec(prev_slot);		/* rec now points to the record of the previous directory slot. Look	for the immediate predecessor of current_rec in a loop. */	while(current_rec != rec) {		prev_rec = rec;		rec = page_rec_get_next(rec);	}	page_cur_move_to_next(cursor);	next_rec = cursor->rec;		/* 3. Remove the record from the linked list of records */	page_rec_set_next(prev_rec, next_rec);	page_header_set_field(page, PAGE_N_RECS,				(ulint)(page_get_n_recs(page) - 1));	/* 4. If the deleted record is pointed to by a dir slot, update the	record pointer in slot. In the following if-clause we assume that	prev_rec is owned by the same slot, i.e., PAGE_DIR_SLOT_MIN_N_OWNED	>= 2. */		ut_ad(PAGE_DIR_SLOT_MIN_N_OWNED >= 2);	ut_ad(cur_n_owned > 1);	if (current_rec == page_dir_slot_get_rec(cur_dir_slot)) {		page_dir_slot_set_rec(cur_dir_slot, prev_rec);	}		/* 5. Update the number of owned records of the slot */	page_dir_slot_set_n_owned(cur_dir_slot, cur_n_owned - 1);	/* 6. Free the memory occupied by the record */	page_mem_free(page, current_rec, offsets);	/* 7. Now we have decremented the number of owned records of the slot.	If the number drops below PAGE_DIR_SLOT_MIN_N_OWNED, we balance the	slots. */		if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) {		page_dir_balance_slot(page, cur_slot_no);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -