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

📄 tsgistidx.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * tsgistidx.c *	  GiST support functions for tsvector_ops * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/utils/adt/tsgistidx.c,v 1.7 2008/01/01 19:45:52 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/gist.h"#include "access/tuptoaster.h"#include "tsearch/ts_type.h"#include "tsearch/ts_utils.h"#include "utils/pg_crc.h"#define SIGLENINT  31			/* >121 => key will toast, so it will not work								 * !!! */#define SIGLEN	( sizeof(int4) * SIGLENINT )#define SIGLENBIT (SIGLEN * BITS_PER_BYTE)typedef char BITVEC[SIGLEN];typedef char *BITVECP;#define LOOPBYTE \			for(i=0;i<SIGLEN;i++)#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )#define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )#define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )#define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITS_PER_BYTE ) )#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)#define HASH(sign, val) SETBIT((sign), HASHVAL(val))#define GETENTRY(vec,pos) ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))/* * type of GiST index key */typedef struct{	int32		vl_len_;		/* varlena header (do not touch directly!) */	int4		flag;	char		data[1];} SignTSVector;#define ARRKEY		0x01#define SIGNKEY		0x02#define ALLISTRUE	0x04#define ISARRKEY(x) ( ((SignTSVector*)(x))->flag & ARRKEY )#define ISSIGNKEY(x)	( ((SignTSVector*)(x))->flag & SIGNKEY )#define ISALLTRUE(x)	( ((SignTSVector*)(x))->flag & ALLISTRUE )#define GTHDRSIZE	( VARHDRSZ + sizeof(int4) )#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )#define GETSIGN(x)	( (BITVECP)( (char*)(x)+GTHDRSIZE ) )#define GETARR(x)	( (int4*)( (char*)(x)+GTHDRSIZE ) )#define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int4) )/* Number of one-bits in an unsigned byte */static const uint8 number_of_ones[256] = {	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};static int4 sizebitvec(BITVECP sign);Datumgtsvectorin(PG_FUNCTION_ARGS){	ereport(ERROR,			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			 errmsg("gtsvector_in not implemented")));	PG_RETURN_DATUM(0);}#define SINGOUTSTR	"%d true bits, %d false bits"#define ARROUTSTR	"%d unique words"#define EXTRALEN	( 2*13 )static int	outbuf_maxlen = 0;Datumgtsvectorout(PG_FUNCTION_ARGS){	SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0)));	char	   *outbuf;	if (outbuf_maxlen == 0)		outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;	outbuf = palloc(outbuf_maxlen);	if (ISARRKEY(key))		sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));	else	{		int			cnttrue = (ISALLTRUE(key)) ? SIGLENBIT : sizebitvec(GETSIGN(key));		sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue);	}	PG_FREE_IF_COPY(key, 0);	PG_RETURN_POINTER(outbuf);}static intcompareint(const void *va, const void *vb){	int4		a = *((int4 *) va);	int4		b = *((int4 *) vb);	if (a == b)		return 0;	return (a > b) ? 1 : -1;}/* * Removes duplicates from an array of int4. 'l' is * size of the input array. Returns the new size of the array. */static intuniqueint(int4 *a, int4 l){	int4	   *ptr,			   *res;	if (l <= 1)		return l;	ptr = res = a;	qsort((void *) a, l, sizeof(int4), compareint);	while (ptr - a < l)		if (*ptr != *res)			*(++res) = *ptr++;		else			ptr++;	return res + 1 - a;}static voidmakesign(BITVECP sign, SignTSVector *a){	int4		k,				len = ARRNELEM(a);	int4	   *ptr = GETARR(a);	MemSet((void *) sign, 0, sizeof(BITVEC));	for (k = 0; k < len; k++)		HASH(sign, ptr[k]);}Datumgtsvector_compress(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	GISTENTRY  *retval = entry;	if (entry->leafkey)	{							/* tsvector */		SignTSVector *res;		TSVector	val = DatumGetTSVector(entry->key);		int4		len;		int4	   *arr;		WordEntry  *ptr = ARRPTR(val);		char	   *words = STRPTR(val);		len = CALCGTSIZE(ARRKEY, val->size);		res = (SignTSVector *) palloc(len);		SET_VARSIZE(res, len);		res->flag = ARRKEY;		arr = GETARR(res);		len = val->size;		while (len--)		{			pg_crc32	c;			INIT_CRC32(c);			COMP_CRC32(c, words + ptr->pos, ptr->len);			FIN_CRC32(c);			*arr = *(int4 *) &c;			arr++;			ptr++;		}		len = uniqueint(GETARR(res), val->size);		if (len != val->size)		{			/*			 * there is a collision of hash-function; len is always less than			 * val->size			 */			len = CALCGTSIZE(ARRKEY, len);			res = (SignTSVector *) repalloc((void *) res, len);			SET_VARSIZE(res, len);		}		/* make signature, if array is too long */		if (VARSIZE(res) > TOAST_INDEX_TARGET)		{			SignTSVector *ressign;			len = CALCGTSIZE(SIGNKEY, 0);			ressign = (SignTSVector *) palloc(len);			SET_VARSIZE(ressign, len);			ressign->flag = SIGNKEY;			makesign(GETSIGN(ressign), res);			res = ressign;		}		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));		gistentryinit(*retval, PointerGetDatum(res),					  entry->rel, entry->page,					  entry->offset, FALSE);	}	else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&			 !ISALLTRUE(DatumGetPointer(entry->key)))	{		int4		i,					len;		SignTSVector *res;		BITVECP		sign = GETSIGN(DatumGetPointer(entry->key));		LOOPBYTE		{			if ((sign[i] & 0xff) != 0xff)				PG_RETURN_POINTER(retval);		}		len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);		res = (SignTSVector *) palloc(len);		SET_VARSIZE(res, len);		res->flag = SIGNKEY | ALLISTRUE;		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));		gistentryinit(*retval, PointerGetDatum(res),					  entry->rel, entry->page,					  entry->offset, FALSE);	}	PG_RETURN_POINTER(retval);}Datumgtsvector_decompress(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));	if (key != (SignTSVector *) DatumGetPointer(entry->key))	{		GISTENTRY  *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));		gistentryinit(*retval, PointerGetDatum(key),					  entry->rel, entry->page,					  entry->offset, FALSE);		PG_RETURN_POINTER(retval);	}	PG_RETURN_POINTER(entry);}typedef struct{	int4	   *arrb;	int4	   *arre;} CHKVAL;/* * is there value 'val' in array or not ? */static boolcheckcondition_arr(void *checkval, QueryOperand *val){	int4	   *StopLow = ((CHKVAL *) checkval)->arrb;	int4	   *StopHigh = ((CHKVAL *) checkval)->arre;	int4	   *StopMiddle;	/* Loop invariant: StopLow <= val < StopHigh */	while (StopLow < StopHigh)	{		StopMiddle = StopLow + (StopHigh - StopLow) / 2;		if (*StopMiddle == val->valcrc)			return (true);		else if (*StopMiddle < val->valcrc)			StopLow = StopMiddle + 1;		else			StopHigh = StopMiddle;	}	return (false);}static boolcheckcondition_bit(void *checkval, QueryOperand *val){	return GETBIT(checkval, HASHVAL(val->valcrc));}Datumgtsvector_consistent(PG_FUNCTION_ARGS){	TSQuery		query = PG_GETARG_TSQUERY(1);	SignTSVector *key = (SignTSVector *) DatumGetPointer(									((GISTENTRY *) PG_GETARG_POINTER(0))->key	);	if (!query->size)		PG_RETURN_BOOL(false);	if (ISSIGNKEY(key))	{		if (ISALLTRUE(key))			PG_RETURN_BOOL(true);		PG_RETURN_BOOL(TS_execute(								  GETQUERY(query),								  (void *) GETSIGN(key), false,								  checkcondition_bit								  ));	}	else	{							/* only leaf pages */		CHKVAL		chkval;		chkval.arrb = GETARR(key);		chkval.arre = chkval.arrb + ARRNELEM(key);		PG_RETURN_BOOL(TS_execute(								  GETQUERY(query),								  (void *) &chkval, true,								  checkcondition_arr								  ));	}}static int4unionkey(BITVECP sbase, SignTSVector *add){	int4		i;	if (ISSIGNKEY(add))	{		BITVECP		sadd = GETSIGN(add);		if (ISALLTRUE(add))			return 1;		LOOPBYTE			sbase[i] |= sadd[i];	}	else	{		int4	   *ptr = GETARR(add);		for (i = 0; i < ARRNELEM(add); i++)			HASH(sbase, ptr[i]);	}	return 0;}Datumgtsvector_union(PG_FUNCTION_ARGS){	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);	int		   *size = (int *) PG_GETARG_POINTER(1);

⌨️ 快捷键说明

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