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

📄 gistutil.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	return curid;}/* * Insert equivalent tuples to left or right page with minimum * penalty */voidgistadjsubkey(Relation r,			  IndexTuple *itup, /* contains compressed entry */			  int len,			  GIST_SPLITVEC *v,			  GISTSTATE *giststate){	int			curlen;	OffsetNumber *curwpos;	GISTENTRY	entry,				identry[INDEX_MAX_KEYS],			   *ev0p,			   *ev1p;	float		lpenalty,				rpenalty;	GistEntryVector *evec;	int			datumsize;	bool		isnull[INDEX_MAX_KEYS];	int			i,				j;	/* clear vectors */	curlen = v->spl_nleft;	curwpos = v->spl_left;	for (i = 0; i < v->spl_nleft; i++)	{		if (v->spl_idgrp[v->spl_left[i]] == 0)		{			*curwpos = v->spl_left[i];			curwpos++;		}		else			curlen--;	}	v->spl_nleft = curlen;	curlen = v->spl_nright;	curwpos = v->spl_right;	for (i = 0; i < v->spl_nright; i++)	{		if (v->spl_idgrp[v->spl_right[i]] == 0)		{			*curwpos = v->spl_right[i];			curwpos++;		}		else			curlen--;	}	v->spl_nright = curlen;	evec = palloc(2 * sizeof(GISTENTRY) + GEVHDRSZ);	evec->n = 2;	ev0p = &(evec->vector[0]);	ev1p = &(evec->vector[1]);	/* add equivalent tuple */	for (i = 0; i < len; i++)	{		Datum		datum;		if (v->spl_idgrp[i + 1] == 0)	/* already inserted */			continue;		gistDeCompressAtt(giststate, r, itup[i], NULL, (OffsetNumber) 0,						  identry, isnull);		v->spl_ngrp[v->spl_idgrp[i + 1]]--;		if (v->spl_ngrp[v->spl_idgrp[i + 1]] == 0 &&			(v->spl_grpflag[v->spl_idgrp[i + 1]] & BOTH_ADDED) != BOTH_ADDED)		{			/* force last in group */			rpenalty = 1.0;			lpenalty = (v->spl_grpflag[v->spl_idgrp[i + 1]] & LEFT_ADDED) ? 2.0 : 0.0;		}		else		{			/* where? */			for (j = 1; j < r->rd_att->natts; j++)			{				gistentryinit(entry, v->spl_lattr[j], r, NULL,							  (OffsetNumber) 0, v->spl_lattrsize[j], FALSE);				gistpenalty(giststate, j, &entry, v->spl_lisnull[j],							&identry[j], isnull[j], &lpenalty);				gistentryinit(entry, v->spl_rattr[j], r, NULL,							  (OffsetNumber) 0, v->spl_rattrsize[j], FALSE);				gistpenalty(giststate, j, &entry, v->spl_risnull[j],							&identry[j], isnull[j], &rpenalty);				if (lpenalty != rpenalty)					break;			}		}		/*		 * add XXX: refactor this to avoid duplicating code		 */		if (lpenalty < rpenalty)		{			v->spl_grpflag[v->spl_idgrp[i + 1]] |= LEFT_ADDED;			v->spl_left[v->spl_nleft] = i + 1;			v->spl_nleft++;			for (j = 1; j < r->rd_att->natts; j++)			{				if (isnull[j] && v->spl_lisnull[j])				{					v->spl_lattr[j] = (Datum) 0;					v->spl_lattrsize[j] = 0;				}				else				{					FILLEV(v->spl_lisnull[j], v->spl_lattr[j], v->spl_lattrsize[j],						   isnull[j], identry[j].key, identry[j].bytes);					datum = FunctionCall2(&giststate->unionFn[j],										  PointerGetDatum(evec),										  PointerGetDatum(&datumsize));					v->spl_lattr[j] = datum;					v->spl_lattrsize[j] = datumsize;					v->spl_lisnull[j] = false;				}			}		}		else		{			v->spl_grpflag[v->spl_idgrp[i + 1]] |= RIGHT_ADDED;			v->spl_right[v->spl_nright] = i + 1;			v->spl_nright++;			for (j = 1; j < r->rd_att->natts; j++)			{				if (isnull[j] && v->spl_risnull[j])				{					v->spl_rattr[j] = (Datum) 0;					v->spl_rattrsize[j] = 0;				}				else				{					FILLEV(v->spl_risnull[j], v->spl_rattr[j], v->spl_rattrsize[j],						   isnull[j], identry[j].key, identry[j].bytes);					datum = FunctionCall2(&giststate->unionFn[j],										  PointerGetDatum(evec),										  PointerGetDatum(&datumsize));					v->spl_rattr[j] = datum;					v->spl_rattrsize[j] = datumsize;					v->spl_risnull[j] = false;				}			}		}	}}/* * find entry with lowest penalty */OffsetNumbergistchoose(Relation r, Page p, IndexTuple it,	/* it has compressed entry */		   GISTSTATE *giststate){	OffsetNumber maxoff;	OffsetNumber i;	OffsetNumber which;	float		sum_grow,				which_grow[INDEX_MAX_KEYS];	GISTENTRY	entry,				identry[INDEX_MAX_KEYS];	bool		isnull[INDEX_MAX_KEYS];	maxoff = PageGetMaxOffsetNumber(p);	*which_grow = -1.0;	which = InvalidOffsetNumber;	sum_grow = 1;	gistDeCompressAtt(giststate, r,					  it, NULL, (OffsetNumber) 0,					  identry, isnull);	for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i))	{		int			j;		IndexTuple	itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));		if (!GistPageIsLeaf(p) && GistTupleIsInvalid(itup))		{			ereport(LOG,					(errmsg("index \"%s\" needs VACUUM or REINDEX to finish crash recovery",							RelationGetRelationName(r))));			continue;		}		sum_grow = 0;		for (j = 0; j < r->rd_att->natts; j++)		{			Datum		datum;			float		usize;			bool		IsNull;			datum = index_getattr(itup, j + 1, giststate->tupdesc, &IsNull);			gistdentryinit(giststate, j, &entry, datum, r, p, i,						   ATTSIZE(datum, giststate->tupdesc, j + 1, IsNull),						   FALSE, IsNull);			gistpenalty(giststate, j, &entry, IsNull,						&identry[j], isnull[j], &usize);			if (which_grow[j] < 0 || usize < which_grow[j])			{				which = i;				which_grow[j] = usize;				if (j < r->rd_att->natts - 1 && i == FirstOffsetNumber)					which_grow[j + 1] = -1;				sum_grow += which_grow[j];			}			else if (which_grow[j] == usize)				sum_grow += usize;			else			{				sum_grow = 1;				break;			}		}	}	if (which == InvalidOffsetNumber)		which = FirstOffsetNumber;	return which;}/* * initialize a GiST entry with a decompressed version of key */voidgistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,			   Datum k, Relation r, Page pg, OffsetNumber o,			   int b, bool l, bool isNull){	if (b && !isNull)	{		GISTENTRY  *dep;		gistentryinit(*e, k, r, pg, o, b, l);		dep = (GISTENTRY *)			DatumGetPointer(FunctionCall1(&giststate->decompressFn[nkey],										  PointerGetDatum(e)));		/* decompressFn may just return the given pointer */		if (dep != e)			gistentryinit(*e, dep->key, dep->rel, dep->page, dep->offset,						  dep->bytes, dep->leafkey);	}	else		gistentryinit(*e, (Datum) 0, r, pg, o, 0, l);}/* * initialize a GiST entry with a compressed version of key */voidgistcentryinit(GISTSTATE *giststate, int nkey,			   GISTENTRY *e, Datum k, Relation r,			   Page pg, OffsetNumber o, int b, bool l, bool isNull){	if (!isNull)	{		GISTENTRY  *cep;		gistentryinit(*e, k, r, pg, o, b, l);		cep = (GISTENTRY *)			DatumGetPointer(FunctionCall1(&giststate->compressFn[nkey],										  PointerGetDatum(e)));		/* compressFn may just return the given pointer */		if (cep != e)			gistentryinit(*e, cep->key, cep->rel, cep->page, cep->offset,						  cep->bytes, cep->leafkey);	}	else		gistentryinit(*e, (Datum) 0, r, pg, o, 0, l);}IndexTuplegistFormTuple(GISTSTATE *giststate, Relation r,			  Datum attdata[], int datumsize[], bool isnull[]){	GISTENTRY	centry[INDEX_MAX_KEYS];	Datum		compatt[INDEX_MAX_KEYS];	int			i;	IndexTuple	res;	for (i = 0; i < r->rd_att->natts; i++)	{		if (isnull[i])			compatt[i] = (Datum) 0;		else		{			gistcentryinit(giststate, i, &centry[i], attdata[i],						   NULL, NULL, (OffsetNumber) 0,						   datumsize[i], FALSE, FALSE);			compatt[i] = centry[i].key;		}	}	res = index_form_tuple(giststate->tupdesc, compatt, isnull);	GistTupleSetValid(res);	return res;}voidgistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,				  OffsetNumber o, GISTENTRY *attdata, bool *isnull){	int			i;	for (i = 0; i < r->rd_att->natts; i++)	{		Datum		datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]);		gistdentryinit(giststate, i, &attdata[i],					   datum, r, p, o,					   ATTSIZE(datum, giststate->tupdesc, i + 1, isnull[i]),					   FALSE, isnull[i]);	}}static voidgistpenalty(GISTSTATE *giststate, int attno,			GISTENTRY *key1, bool isNull1,			GISTENTRY *key2, bool isNull2, float *penalty){	if (giststate->penaltyFn[attno].fn_strict && (isNull1 || isNull2))		*penalty = 0.0;	else		FunctionCall3(&giststate->penaltyFn[attno],					  PointerGetDatum(key1),					  PointerGetDatum(key2),					  PointerGetDatum(penalty));}voidGISTInitBuffer(Buffer b, uint32 f){	GISTPageOpaque opaque;	Page		page;	Size		pageSize;	pageSize = BufferGetPageSize(b);	page = BufferGetPage(b);	PageInit(page, pageSize, sizeof(GISTPageOpaqueData));	opaque = GistPageGetOpaque(page);	opaque->flags = f;	opaque->rightlink = InvalidBlockNumber;	memset(&(opaque->nsn), 0, sizeof(GistNSN));}voidgistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v,				  IndexTuple *itup, int len, GISTSTATE *giststate){	/*	 * now let the user-defined picksplit function set up the split vector; in	 * entryvec have no null value!!	 */	FunctionCall2(&giststate->picksplitFn[0],				  PointerGetDatum(entryvec),				  PointerGetDatum(v));	/* compatibility with old code */	if (v->spl_left[v->spl_nleft - 1] == InvalidOffsetNumber)		v->spl_left[v->spl_nleft - 1] = (OffsetNumber) (entryvec->n - 1);	if (v->spl_right[v->spl_nright - 1] == InvalidOffsetNumber)		v->spl_right[v->spl_nright - 1] = (OffsetNumber) (entryvec->n - 1);	v->spl_lattr[0] = v->spl_ldatum;	v->spl_rattr[0] = v->spl_rdatum;	v->spl_lisnull[0] = false;	v->spl_risnull[0] = false;	/*	 * if index is multikey, then we must to try get smaller bounding box for	 * subkey(s)	 */	if (r->rd_att->natts > 1)	{		int			MaxGrpId;		v->spl_idgrp = (int *) palloc0(sizeof(int) * entryvec->n);		v->spl_grpflag = (char *) palloc0(sizeof(char) * entryvec->n);		v->spl_ngrp = (int *) palloc(sizeof(int) * entryvec->n);		MaxGrpId = gistfindgroup(giststate, entryvec->vector, v);		/* form union of sub keys for each page (l,p) */		gistunionsubkey(r, giststate, itup, v, false);		/*		 * if possible, we insert equivalent tuples with control by penalty		 * for a subkey(s)		 */		if (MaxGrpId > 1)			gistadjsubkey(r, itup, len, v, giststate);	}}BuffergistNewBuffer(Relation r){	Buffer		buffer = InvalidBuffer;	bool		needLock;	while (true)	{		BlockNumber blkno = GetFreeIndexPage(&r->rd_node);		if (blkno == InvalidBlockNumber)			break;		buffer = ReadBuffer(r, blkno);		if (ConditionalLockBuffer(buffer))		{			Page		page = BufferGetPage(buffer);			if (GistPageIsDeleted(page))			{				GistPageSetNonDeleted(page);				return buffer;			}			else				LockBuffer(buffer, GIST_UNLOCK);		}		ReleaseBuffer(buffer);	}	needLock = !RELATION_IS_LOCAL(r);	if (needLock)		LockRelationForExtension(r, ExclusiveLock);	buffer = ReadBuffer(r, P_NEW);	LockBuffer(buffer, GIST_EXCLUSIVE);	if (needLock)		UnlockRelationForExtension(r, ExclusiveLock);	return buffer;}

⌨️ 快捷键说明

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