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

📄 ginutil.c

📁 postgresql8.3.4源码,开源数据库
💻 C
字号:
/*------------------------------------------------------------------------- * * ginutil.c *	  utilities routines for the postgres inverted index access method. * * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *			$PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.13 2008/01/01 19:45:46 momjian Exp $ *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/gin.h"#include "access/heapam.h"#include "access/reloptions.h"#include "storage/freespace.h"voidinitGinState(GinState *state, Relation index){	if (index->rd_att->natts != 1)		elog(ERROR, "numberOfAttributes %d != 1",			 index->rd_att->natts);	state->tupdesc = index->rd_att;	fmgr_info_copy(&(state->compareFn),				   index_getprocinfo(index, 1, GIN_COMPARE_PROC),				   CurrentMemoryContext);	fmgr_info_copy(&(state->extractValueFn),				   index_getprocinfo(index, 1, GIN_EXTRACTVALUE_PROC),				   CurrentMemoryContext);	fmgr_info_copy(&(state->extractQueryFn),				   index_getprocinfo(index, 1, GIN_EXTRACTQUERY_PROC),				   CurrentMemoryContext);	fmgr_info_copy(&(state->consistentFn),				   index_getprocinfo(index, 1, GIN_CONSISTENT_PROC),				   CurrentMemoryContext);}/* * Allocate a new page (either by recycling, or by extending the index file) * The returned buffer is already pinned and exclusive-locked * Caller is responsible for initializing the page by calling GinInitBuffer */BufferGinNewBuffer(Relation index){	Buffer		buffer;	bool		needLock;	/* First, try to get a page from FSM */	for (;;)	{		BlockNumber blkno = GetFreeIndexPage(&index->rd_node);		if (blkno == InvalidBlockNumber)			break;		buffer = ReadBuffer(index, blkno);		/*		 * We have to guard against the possibility that someone else already		 * recycled this page; the buffer may be locked if so.		 */		if (ConditionalLockBuffer(buffer))		{			Page		page = BufferGetPage(buffer);			if (PageIsNew(page))				return buffer;	/* OK to use, if never initialized */			if (GinPageIsDeleted(page))				return buffer;	/* OK to use */			LockBuffer(buffer, GIN_UNLOCK);		}		/* Can't use it, so release buffer and try again */		ReleaseBuffer(buffer);	}	/* Must extend the file */	needLock = !RELATION_IS_LOCAL(index);	if (needLock)		LockRelationForExtension(index, ExclusiveLock);	buffer = ReadBuffer(index, P_NEW);	LockBuffer(buffer, GIN_EXCLUSIVE);	if (needLock)		UnlockRelationForExtension(index, ExclusiveLock);	return buffer;}voidGinInitPage(Page page, uint32 f, Size pageSize){	GinPageOpaque opaque;	PageInit(page, pageSize, sizeof(GinPageOpaqueData));	opaque = GinPageGetOpaque(page);	memset(opaque, 0, sizeof(GinPageOpaqueData));	opaque->flags = f;	opaque->rightlink = InvalidBlockNumber;}voidGinInitBuffer(Buffer b, uint32 f){	GinInitPage(BufferGetPage(b), f, BufferGetPageSize(b));}intcompareEntries(GinState *ginstate, Datum a, Datum b){	return DatumGetInt32(						 FunctionCall2(									   &ginstate->compareFn,									   a, b									   )		);}typedef struct{	FmgrInfo   *cmpDatumFunc;	bool	   *needUnique;} cmpEntriesData;static intcmpEntries(const Datum *a, const Datum *b, cmpEntriesData *arg){	int			res = DatumGetInt32(FunctionCall2(arg->cmpDatumFunc,												  *a, *b));	if (res == 0)		*(arg->needUnique) = TRUE;	return res;}Datum *extractEntriesS(GinState *ginstate, Datum value, int32 *nentries,				bool *needUnique){	Datum	   *entries;	entries = (Datum *) DatumGetPointer(FunctionCall2(												   &ginstate->extractValueFn,													  value,													PointerGetDatum(nentries)													  ));	if (entries == NULL)		*nentries = 0;	*needUnique = FALSE;	if (*nentries > 1)	{		cmpEntriesData arg;		arg.cmpDatumFunc = &ginstate->compareFn;		arg.needUnique = needUnique;		qsort_arg(entries, *nentries, sizeof(Datum),				  (qsort_arg_comparator) cmpEntries, (void *) &arg);	}	return entries;}Datum *extractEntriesSU(GinState *ginstate, Datum value, int32 *nentries){	bool		needUnique;	Datum	   *entries = extractEntriesS(ginstate, value, nentries,										  &needUnique);	if (needUnique)	{		Datum	   *ptr,				   *res;		ptr = res = entries;		while (ptr - entries < *nentries)		{			if (compareEntries(ginstate, *ptr, *res) != 0)				*(++res) = *ptr++;			else				ptr++;		}		*nentries = res + 1 - entries;	}	return entries;}/* * It's analog of PageGetTempPage(), but copies whole page */PageGinPageGetCopyPage(Page page){	Size		pageSize = PageGetPageSize(page);	Page		tmppage;	tmppage = (Page) palloc(pageSize);	memcpy(tmppage, page, pageSize);	return tmppage;}Datumginoptions(PG_FUNCTION_ARGS){	Datum		reloptions = PG_GETARG_DATUM(0);	bool		validate = PG_GETARG_BOOL(1);	bytea	   *result;	/*	 * It's not clear that fillfactor is useful for GIN, but for the moment	 * we'll accept it anyway.  (It won't do anything...)	 */#define GIN_MIN_FILLFACTOR			10#define GIN_DEFAULT_FILLFACTOR		100	result = default_reloptions(reloptions, validate,								GIN_MIN_FILLFACTOR,								GIN_DEFAULT_FILLFACTOR);	if (result)		PG_RETURN_BYTEA_P(result);	PG_RETURN_NULL();}

⌨️ 快捷键说明

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