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

📄 gist.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
	InsertIndexResult res;	GISTENTRY	tmpentry;	IndexTuple	newtup;	b = ReadBuffer(r, stk->gs_blk);	p = BufferGetPage(b);	if (gistnospace(p, ltup))	{		res = gistSplit(r, b, stk->gs_parent, ltup, giststate);		WriteBuffer(b);			/* don't forget to release buffer!  -								 * 01/31/94 */		pfree(res);		gistdoinsert(r, rtup, giststate);	}	else	{		gistPageAddItem(giststate, r, p, (Item) ltup,						IndexTupleSize(ltup), InvalidOffsetNumber,						LP_USED, &tmpentry, &newtup);		WriteBuffer(b);		gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,					   tmpentry.bytes, giststate);		/* be tidy */		if (tmpentry.pred != (((char *) ltup) + sizeof(IndexTupleData)))			pfree(tmpentry.pred);		if (ltup != newtup)			pfree(newtup);		gistentryinsert(r, stk, rtup, giststate);	}}/*** Insert an entry onto a page*/static InsertIndexResultgistentryinsert(Relation r, GISTSTACK *stk, IndexTuple tup,				GISTSTATE *giststate){	Buffer		b;	Page		p;	InsertIndexResult res;	OffsetNumber off;	GISTENTRY	tmpentry;	IndexTuple	newtup;	b = ReadBuffer(r, stk->gs_blk);	p = BufferGetPage(b);	if (gistnospace(p, tup))	{		res = gistSplit(r, b, stk->gs_parent, tup, giststate);		WriteBuffer(b);			/* don't forget to release buffer!  -								 * 01/31/94 */		return res;	}	else	{		res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));		off = gistPageAddItem(giststate, r, p, (Item) tup, IndexTupleSize(tup),					   InvalidOffsetNumber, LP_USED, &tmpentry, &newtup);		WriteBuffer(b);		ItemPointerSet(&(res->pointerData), stk->gs_blk, off);		gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,					   tmpentry.bytes, giststate);		/* be tidy */		if (tmpentry.pred != (((char *) tup) + sizeof(IndexTupleData)))			pfree(tmpentry.pred);		if (tup != newtup)			pfree(newtup);		return res;	}}static voidgistnewroot(GISTSTATE *giststate, Relation r, IndexTuple lt, IndexTuple rt){	Buffer		b;	Page		p;	GISTENTRY	tmpentry;	IndexTuple	newtup;	b = ReadBuffer(r, GISTP_ROOT);	GISTInitBuffer(b, 0);	p = BufferGetPage(b);	gistPageAddItem(giststate, r, p, (Item) lt, IndexTupleSize(lt),					FirstOffsetNumber,					LP_USED, &tmpentry, &newtup);	/* be tidy */	if (tmpentry.pred != (((char *) lt) + sizeof(IndexTupleData)))		pfree(tmpentry.pred);	if (lt != newtup)		pfree(newtup);	gistPageAddItem(giststate, r, p, (Item) rt, IndexTupleSize(rt),					OffsetNumberNext(FirstOffsetNumber), LP_USED,					&tmpentry, &newtup);	/* be tidy */	if (tmpentry.pred != (((char *) rt) + sizeof(IndexTupleData)))		pfree(tmpentry.pred);	if (rt != newtup)		pfree(newtup);	WriteBuffer(b);}static voidGISTInitBuffer(Buffer b, uint32 f){	GISTPageOpaque opaque;	Page		page;	Size		pageSize;	pageSize = BufferGetPageSize(b);	page = BufferGetPage(b);	MemSet(page, 0, (int) pageSize);	PageInit(page, pageSize, sizeof(GISTPageOpaqueData));	opaque = (GISTPageOpaque) PageGetSpecialPointer(page);	opaque->flags = f;}/*** find entry with lowest penalty*/static OffsetNumbergistchoose(Relation r, Page p, IndexTuple it,	/* it has compressed entry */		   GISTSTATE *giststate){	OffsetNumber maxoff;	OffsetNumber i;	char	   *id;	char	   *datum;	float		usize;	OffsetNumber which;	float		which_grow;	GISTENTRY	entry,				identry;	int			size,				idsize;	idsize = IndexTupleSize(it) - sizeof(IndexTupleData);	id = ((char *) it) + sizeof(IndexTupleData);	maxoff = PageGetMaxOffsetNumber(p);	which_grow = -1.0;	which = -1;	gistdentryinit(giststate, &identry, id, (Relation) NULL, (Page) NULL,				   (OffsetNumber) 0, idsize, FALSE);	for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))	{		datum = (char *) PageGetItem(p, PageGetItemId(p, i));		size = IndexTupleSize(datum) - sizeof(IndexTupleData);		datum += sizeof(IndexTupleData);		gistdentryinit(giststate, &entry, datum, r, p, i, size, FALSE);		(*fmgr_faddr(&giststate->penaltyFn)) (&entry, &identry, &usize);		if (which_grow < 0 || usize < which_grow)		{			which = i;			which_grow = usize;			if (which_grow == 0)				break;		}		if (entry.pred != datum)			pfree(entry.pred);	}	if (identry.pred != id)		pfree(identry.pred);	return which;}static intgistnospace(Page p, IndexTuple it){	return PageGetFreeSpace(p) < IndexTupleSize(it);}voidgistfreestack(GISTSTACK *s){	GISTSTACK  *p;	while (s != (GISTSTACK *) NULL)	{		p = s->gs_parent;		pfree(s);		s = p;	}}/*** remove an entry from a page*/voidgistdelete(Relation r, ItemPointer tid){	BlockNumber blkno;	OffsetNumber offnum;	Buffer		buf;	Page		page;	/*	 * Notes in ExecUtils:ExecOpenIndices() Also note that only vacuum	 * deletes index tuples now...	 *	 * RelationSetLockForWrite(r);	 */	blkno = ItemPointerGetBlockNumber(tid);	offnum = ItemPointerGetOffsetNumber(tid);	/* adjust any scans that will be affected by this deletion */	gistadjscans(r, GISTOP_DEL, blkno, offnum);	/* delete the index tuple */	buf = ReadBuffer(r, blkno);	page = BufferGetPage(buf);	PageIndexTupleDelete(page, offnum);	WriteBuffer(buf);}voidinitGISTstate(GISTSTATE *giststate, Relation index){	RegProcedure consistent_proc,				union_proc,				compress_proc,				decompress_proc;	RegProcedure penalty_proc,				picksplit_proc,				equal_proc;	HeapTuple	htup;	Form_pg_index itupform;	consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC);	union_proc = index_getprocid(index, 1, GIST_UNION_PROC);	compress_proc = index_getprocid(index, 1, GIST_COMPRESS_PROC);	decompress_proc = index_getprocid(index, 1, GIST_DECOMPRESS_PROC);	penalty_proc = index_getprocid(index, 1, GIST_PENALTY_PROC);	picksplit_proc = index_getprocid(index, 1, GIST_PICKSPLIT_PROC);	equal_proc = index_getprocid(index, 1, GIST_EQUAL_PROC);	fmgr_info(consistent_proc, &giststate->consistentFn);	fmgr_info(union_proc, &giststate->unionFn);	fmgr_info(compress_proc, &giststate->compressFn);	fmgr_info(decompress_proc, &giststate->decompressFn);	fmgr_info(penalty_proc, &giststate->penaltyFn);	fmgr_info(picksplit_proc, &giststate->picksplitFn);	fmgr_info(equal_proc, &giststate->equalFn);	/* see if key type is different from type of attribute being indexed */	htup = SearchSysCacheTuple(INDEXRELID,							   ObjectIdGetDatum(RelationGetRelid(index)),							   0, 0, 0);	itupform = (Form_pg_index) GETSTRUCT(htup);	if (!HeapTupleIsValid(htup))		elog(ERROR, "initGISTstate: index %u not found",			 RelationGetRelid(index));	giststate->haskeytype = itupform->indhaskeytype;	if (giststate->haskeytype)	{		/* key type is different -- is it byval? */		htup = SearchSysCacheTuple(ATTNUM,								   ObjectIdGetDatum(itupform->indexrelid),								   UInt16GetDatum(FirstOffsetNumber),								   0, 0);		if (!HeapTupleIsValid(htup))		{			elog(ERROR, "initGISTstate: no attribute tuple %u %d",				 itupform->indexrelid, FirstOffsetNumber);			return;		}		giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval);	}	else		giststate->keytypbyval = FALSE;	return;}/*** Given an IndexTuple to be inserted on a page, this routine replaces** the key with another key, which may involve generating a new IndexTuple** if the sizes don't match*/static IndexTuplegist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t){	char	   *datum = (((char *) t) + sizeof(IndexTupleData));	/* if new entry fits in index tuple, copy it in */	if (entry.bytes < IndexTupleSize(t) - sizeof(IndexTupleData))	{		memcpy(datum, entry.pred, entry.bytes);		/* clear out old size */		t->t_info &= 0xe000;		/* or in new size */		t->t_info |= MAXALIGN(entry.bytes + sizeof(IndexTupleData));		return t;	}	else	{		/* generate a new index tuple for the compressed entry */		TupleDesc	tupDesc = r->rd_att;		IndexTuple	newtup;		char	   *isnull;		int			blank;		isnull = (char *) palloc(r->rd_rel->relnatts);		for (blank = 0; blank < r->rd_rel->relnatts; blank++)			isnull[blank] = ' ';		newtup = (IndexTuple) index_formtuple(tupDesc,											  (Datum *) &(entry.pred),											  isnull);		newtup->t_tid = t->t_tid;		pfree(isnull);		return newtup;	}}/*** initialize a GiST entry with a decompressed version of pred*/voidgistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,			   Page pg, OffsetNumber o, int b, bool l){	GISTENTRY  *dep;	gistentryinit(*e, pr, r, pg, o, b, l);	if (giststate->haskeytype)	{		dep = (GISTENTRY *) ((*fmgr_faddr(&giststate->decompressFn)) (e));		gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,					  dep->leafkey);		if (dep != e)			pfree(dep);	}}/*** initialize a GiST entry with a compressed version of pred*/static voidgistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,			   Page pg, OffsetNumber o, int b, bool l){	GISTENTRY  *cep;	gistentryinit(*e, pr, r, pg, o, b, l);	if (giststate->haskeytype)	{		cep = (GISTENTRY *) ((*fmgr_faddr(&giststate->compressFn)) (e));		gistentryinit(*e, cep->pred, cep->rel, cep->page, cep->offset, cep->bytes,					  cep->leafkey);		if (cep != e)			pfree(cep);	}}#ifdef GISTDEBUG/*** sloppy debugging support routine, requires recompilation with appropriate** "out" method for the index keys.  Could be fixed to find that info** in the catalogs...*/void_gistdump(Relation r){	Buffer		buf;	Page		page;	OffsetNumber offnum,				maxoff;	BlockNumber blkno;	BlockNumber nblocks;	GISTPageOpaque po;	IndexTuple	itup;	BlockNumber itblkno;	OffsetNumber itoffno;	char	   *datum;	char	   *itkey;	nblocks = RelationGetNumberOfBlocks(r);	for (blkno = 0; blkno < nblocks; blkno++)	{		buf = ReadBuffer(r, blkno);		page = BufferGetPage(buf);		po = (GISTPageOpaque) PageGetSpecialPointer(page);		maxoff = PageGetMaxOffsetNumber(page);		printf("Page %d maxoff %d <%s>\n", blkno, maxoff,			   (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));		if (PageIsEmpty(page))		{			ReleaseBuffer(buf);			continue;		}		for (offnum = FirstOffsetNumber;			 offnum <= maxoff;			 offnum = OffsetNumberNext(offnum))		{			itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));			itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));			itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));			datum = ((char *) itup);			datum += sizeof(IndexTupleData);			/* get out function for type of key, and out it! */			itkey = (char *) int_range_out((INTRANGE *) datum);			/* itkey = " unable to print"; */			printf("\t[%d] size %d heap <%d,%d> key:%s\n",				   offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);			pfree(itkey);		}		ReleaseBuffer(buf);	}}static char *int_range_out(INTRANGE *r){	char	   *result;	if (r == NULL)		return NULL;	result = (char *) palloc(80);	snprintf(result, 80, "[%d,%d): %d", r->lower, r->upper, r->flag);	return result;}#endif	 /* defined GISTDEBUG */

⌨️ 快捷键说明

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