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

📄 page0cur.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************The page cursor(c) 1994-1996 Innobase OyCreated 10/4/1994 Heikki Tuuri*************************************************************************/#include "page0cur.h"#ifdef UNIV_NONINL#include "page0cur.ic"#endif#include "rem0cmp.h"#include "mtr0log.h"#include "log0recv.h"#include "rem0cmp.h"static ulint	page_rnd	= 976722341;#ifdef PAGE_CUR_ADAPT# ifdef UNIV_SEARCH_PERF_STATulint	page_cur_short_succ	= 0;# endif /* UNIV_SEARCH_PERF_STAT *//********************************************************************Tries a search shortcut based on the last insert. */UNIV_INLINEiboolpage_cur_try_search_shortcut(/*=========================*/				/* out: TRUE on success */	page_t*		page,	/* in: index page */	dict_index_t*	index,	/* in: record descriptor */	dtuple_t*	tuple,	/* in: data tuple */	ulint*		iup_matched_fields,				/* in/out: already matched fields in upper				limit record */	ulint*		iup_matched_bytes,				/* in/out: already matched bytes in a field				not yet completely matched */	ulint*		ilow_matched_fields,				/* in/out: already matched fields in lower				limit record */	ulint*		ilow_matched_bytes,				/* in/out: already matched bytes in a field				not yet completely matched */	page_cur_t*	cursor) /* out: page cursor */ {	rec_t*	rec;	rec_t*	next_rec;	ulint	low_match;	ulint	low_bytes;	ulint	up_match;	ulint	up_bytes;#ifdef UNIV_SEARCH_DEBUG	page_cur_t cursor2;#endif	ibool		success		= FALSE;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	ut_ad(dtuple_check_typed(tuple));	rec = page_header_get_ptr(page, PAGE_LAST_INSERT);	offsets = rec_get_offsets(rec, index, offsets,				dtuple_get_n_fields(tuple), &heap);	ut_ad(rec);	ut_ad(page_rec_is_user_rec(rec));	ut_pair_min(&low_match, &low_bytes,			*ilow_matched_fields, *ilow_matched_bytes,			*iup_matched_fields, *iup_matched_bytes);	up_match = low_match;	up_bytes = low_bytes;	if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets,						&low_match, &low_bytes) < 0) {		goto exit_func;	}	next_rec = page_rec_get_next(rec);	offsets = rec_get_offsets(next_rec, index, offsets,				dtuple_get_n_fields(tuple), &heap);	if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,						&up_match, &up_bytes) >= 0) {		goto exit_func;	}	cursor->rec = rec;#ifdef UNIV_SEARCH_DEBUG	page_cur_search_with_match(page, index, tuple, PAGE_CUR_DBG,	    					iup_matched_fields,	    					iup_matched_bytes,	    					ilow_matched_fields,	    					ilow_matched_bytes,	    					&cursor2);	ut_a(cursor2.rec == cursor->rec);	if (next_rec != page_get_supremum_rec(page)) {		ut_a(*iup_matched_fields == up_match);		ut_a(*iup_matched_bytes == up_bytes);	}	ut_a(*ilow_matched_fields == low_match);	ut_a(*ilow_matched_bytes == low_bytes);#endif	if (!page_rec_is_supremum(next_rec)) {		*iup_matched_fields = up_match;		*iup_matched_bytes = up_bytes;	}	*ilow_matched_fields = low_match;	*ilow_matched_bytes = low_bytes;#ifdef UNIV_SEARCH_PERF_STAT	page_cur_short_succ++;#endif	success = TRUE;exit_func:	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	return(success);}#endif#ifdef PAGE_CUR_LE_OR_EXTENDS/********************************************************************Checks if the nth field in a record is a character type field which extendsthe nth field in tuple, i.e., the field is longer or equal in length and hascommon first characters. */staticiboolpage_cur_rec_field_extends(/*=======================*/				/* out: TRUE if rec field				extends tuple field */	dtuple_t*	tuple,	/* in: data tuple */	rec_t*		rec,	/* in: record */	const ulint*	offsets,/* in: array returned by rec_get_offsets() */	ulint		n)	/* in: compare nth field */{        dtype_t* type;        dfield_t* dfield;        byte*     rec_f;        ulint     rec_f_len;	ut_ad(rec_offs_validate(rec, NULL, offsets));        dfield = dtuple_get_nth_field(tuple, n);        type = dfield_get_type(dfield);	rec_f = rec_get_nth_field(rec, offsets, n, &rec_f_len);        if (type->mtype == DATA_VARCHAR           || type->mtype == DATA_CHAR           || type->mtype == DATA_FIXBINARY           || type->mtype == DATA_BINARY           || type->mtype == DATA_BLOB           || type->mtype == DATA_VARMYSQL           || type->mtype == DATA_MYSQL) {                if (dfield_get_len(dfield) != UNIV_SQL_NULL                    && rec_f_len != UNIV_SQL_NULL                    && rec_f_len >= dfield_get_len(dfield)                    && 0 == cmp_data_data_slow(type, dfield_get_data(dfield),                                      dfield_get_len(dfield),       				       rec_f, dfield_get_len(dfield))) {	                return(TRUE);		}	}        return(FALSE);}#endif /* PAGE_CUR_LE_OR_EXTENDS *//********************************************************************Searches the right position for a page cursor. */voidpage_cur_search_with_match(/*=======================*/	page_t*		page,	/* in: index page */	dict_index_t*	index,	/* in: record descriptor */	dtuple_t*	tuple,	/* in: data tuple */	ulint		mode,	/* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,				or PAGE_CUR_GE */	ulint*		iup_matched_fields,				/* in/out: already matched fields in upper				limit record */	ulint*		iup_matched_bytes,				/* in/out: already matched bytes in a field				not yet completely matched */	ulint*		ilow_matched_fields,				/* in/out: already matched fields in lower				limit record */	ulint*		ilow_matched_bytes,				/* in/out: already matched bytes in a field				not yet completely matched */	page_cur_t*	cursor) /* out: page cursor */ {	ulint	up;		ulint	low;		ulint	mid;	page_dir_slot_t* slot;	rec_t*	up_rec;	rec_t*	low_rec;	rec_t*	mid_rec;	ulint	up_matched_fields;	ulint	up_matched_bytes;	ulint	low_matched_fields;	ulint	low_matched_bytes;	ulint	cur_matched_fields;	ulint	cur_matched_bytes;	int	cmp;#ifdef UNIV_SEARCH_DEBUG	int	dbg_cmp;	ulint	dbg_matched_fields;	ulint	dbg_matched_bytes;#endif	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes	      && ilow_matched_fields && ilow_matched_bytes && cursor);	ut_ad(dtuple_validate(tuple));	ut_ad(dtuple_check_typed(tuple));#ifdef UNIV_DEBUG# ifdef PAGE_CUR_DBG	if (mode != PAGE_CUR_DBG)# endif /* PAGE_CUR_DBG */# ifdef PAGE_CUR_LE_OR_EXTENDS		if (mode != PAGE_CUR_LE_OR_EXTENDS)# endif /* PAGE_CUR_LE_OR_EXTENDS */	ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE)	      || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE));#endif /* UNIV_DEBUG */	page_check_dir(page);#ifdef PAGE_CUR_ADAPT	if ((page_header_get_field(page, PAGE_LEVEL) == 0)	    && (mode == PAGE_CUR_LE)	    && (page_header_get_field(page, PAGE_N_DIRECTION) > 3)	    && (page_header_get_ptr(page, PAGE_LAST_INSERT))	    && (page_header_get_field(page, PAGE_DIRECTION) == PAGE_RIGHT)) {		if (page_cur_try_search_shortcut(page, index, tuple,	    					iup_matched_fields,	    					iup_matched_bytes,	    					ilow_matched_fields,	    					ilow_matched_bytes,	    					cursor)) {	    		return;	    	}	}# ifdef PAGE_CUR_DBG	if (mode == PAGE_CUR_DBG) {		mode = PAGE_CUR_LE;	}# endif#endif		/* The following flag does not work for non-latin1 char sets because	cmp_full_field does not tell how many bytes matched */#ifdef PAGE_CUR_LE_OR_EXTENDS	ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); #endif /* PAGE_CUR_LE_OR_EXTENDS */	/* If mode PAGE_CUR_G is specified, we are trying to position the	cursor to answer a query of the form "tuple < X", where tuple is	the input parameter, and X denotes an arbitrary physical record on	the page. We want to position the cursor on the first X which	satisfies the condition. */	up_matched_fields  = *iup_matched_fields;	up_matched_bytes   = *iup_matched_bytes;	low_matched_fields = *ilow_matched_fields;	low_matched_bytes  = *ilow_matched_bytes;	/* Perform binary search. First the search is done through the page	directory, after that as a linear search in the list of records	owned by the upper limit directory slot. */	low = 0;	up = page_dir_get_n_slots(page) - 1;	/* Perform binary search until the lower and upper limit directory	slots come to the distance 1 of each other */   	while (up - low > 1) {		mid = (low + up) / 2;		slot = page_dir_get_nth_slot(page, mid);		mid_rec = page_dir_slot_get_rec(slot);		ut_pair_min(&cur_matched_fields, &cur_matched_bytes,				low_matched_fields, low_matched_bytes,				up_matched_fields, up_matched_bytes);		offsets = rec_get_offsets(mid_rec, index, offsets,					dtuple_get_n_fields_cmp(tuple), &heap);		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,						&cur_matched_fields,						&cur_matched_bytes);		if (UNIV_LIKELY(cmp > 0)) {low_slot_match:			low = mid;			low_matched_fields = cur_matched_fields;			low_matched_bytes = cur_matched_bytes;		} else if (UNIV_LIKELY(cmp /* == -1 */)) {#ifdef PAGE_CUR_LE_OR_EXTENDS			if (mode == PAGE_CUR_LE_OR_EXTENDS			    && page_cur_rec_field_extends(tuple, mid_rec,						offsets, cur_matched_fields)) {				goto low_slot_match;			}#endif /* PAGE_CUR_LE_OR_EXTENDS */up_slot_match:			up = mid;			up_matched_fields = cur_matched_fields;			up_matched_bytes = cur_matched_bytes;		} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE#ifdef PAGE_CUR_LE_OR_EXTENDS			   || mode == PAGE_CUR_LE_OR_EXTENDS#endif /* PAGE_CUR_LE_OR_EXTENDS */		) {			goto low_slot_match;		} else {			goto up_slot_match;		}   	}	slot = page_dir_get_nth_slot(page, low);	low_rec = page_dir_slot_get_rec(slot);	slot = page_dir_get_nth_slot(page, up);	up_rec = page_dir_slot_get_rec(slot);	/* Perform linear search until the upper and lower records come to	distance 1 of each other. */   	while (page_rec_get_next(low_rec) != up_rec) {		mid_rec = page_rec_get_next(low_rec);		ut_pair_min(&cur_matched_fields, &cur_matched_bytes,				low_matched_fields, low_matched_bytes,				up_matched_fields, up_matched_bytes);		offsets = rec_get_offsets(mid_rec, index, offsets,					dtuple_get_n_fields_cmp(tuple), &heap);		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,						&cur_matched_fields,						&cur_matched_bytes);		if (UNIV_LIKELY(cmp > 0)) {low_rec_match:			low_rec = mid_rec;			low_matched_fields = cur_matched_fields;			low_matched_bytes = cur_matched_bytes;		} else if (UNIV_LIKELY(cmp /* == -1 */)) {#ifdef PAGE_CUR_LE_OR_EXTENDS			if (mode == PAGE_CUR_LE_OR_EXTENDS			    && page_cur_rec_field_extends(tuple, mid_rec,						offsets, cur_matched_fields)) {				goto low_rec_match;			}#endif /* PAGE_CUR_LE_OR_EXTENDS */up_rec_match:			up_rec = mid_rec;			up_matched_fields = cur_matched_fields;			up_matched_bytes = cur_matched_bytes;		} else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE#ifdef PAGE_CUR_LE_OR_EXTENDS			   || mode == PAGE_CUR_LE_OR_EXTENDS#endif /* PAGE_CUR_LE_OR_EXTENDS */		) {			goto low_rec_match;		} else {			goto up_rec_match;		}   	}#ifdef UNIV_SEARCH_DEBUG	/* Check that the lower and upper limit records have the	right alphabetical order compared to tuple. */	dbg_matched_fields = 0;	dbg_matched_bytes = 0;	offsets = rec_get_offsets(low_rec, index, offsets,						ULINT_UNDEFINED, &heap);	dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets,						&dbg_matched_fields,						&dbg_matched_bytes);	if (mode == PAGE_CUR_G) {		ut_a(dbg_cmp >= 0);	} else if (mode == PAGE_CUR_GE) {		ut_a(dbg_cmp == 1);	} else if (mode == PAGE_CUR_L) {		ut_a(dbg_cmp == 1);	} else if (mode == PAGE_CUR_LE) {		ut_a(dbg_cmp >= 0);	}	if (low_rec != page_get_infimum_rec(page)) {			ut_a(low_matched_fields == dbg_matched_fields);		ut_a(low_matched_bytes == dbg_matched_bytes);	}	dbg_matched_fields = 0;	dbg_matched_bytes = 0;	offsets = rec_get_offsets(up_rec, index, offsets,						ULINT_UNDEFINED, &heap);	dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets,						&dbg_matched_fields,						&dbg_matched_bytes);	if (mode == PAGE_CUR_G) {		ut_a(dbg_cmp == -1);	} else if (mode == PAGE_CUR_GE) {		ut_a(dbg_cmp <= 0);	} else if (mode == PAGE_CUR_L) {		ut_a(dbg_cmp <= 0);	} else if (mode == PAGE_CUR_LE) {		ut_a(dbg_cmp == -1);	}	if (up_rec != page_get_supremum_rec(page)) {		ut_a(up_matched_fields == dbg_matched_fields);		ut_a(up_matched_bytes == dbg_matched_bytes);	}#endif	if (mode <= PAGE_CUR_GE) {		cursor->rec = up_rec;	} else {		cursor->rec = low_rec;	}	*iup_matched_fields  = up_matched_fields;	*iup_matched_bytes   = up_matched_bytes;	*ilow_matched_fields = low_matched_fields;	*ilow_matched_bytes  = low_matched_bytes;	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}}/***************************************************************Positions a page cursor on a randomly chosen user record on a page. If there

⌨️ 快捷键说明

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