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

📄 hashutil.c

📁 postgresql8.3.4源码,开源数据库
💻 C
字号:
/*------------------------------------------------------------------------- * * hashutil.c *	  Utility code for Postgres hash implementation. * * 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/hash/hashutil.c,v 1.53 2008/01/01 19:45:46 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/hash.h"#include "access/reloptions.h"#include "executor/execdebug.h"#include "utils/lsyscache.h"/* * _hash_checkqual -- does the index tuple satisfy the scan conditions? */bool_hash_checkqual(IndexScanDesc scan, IndexTuple itup){	TupleDesc	tupdesc = RelationGetDescr(scan->indexRelation);	ScanKey		key = scan->keyData;	int			scanKeySize = scan->numberOfKeys;	IncrIndexProcessed();	while (scanKeySize > 0)	{		Datum		datum;		bool		isNull;		Datum		test;		datum = index_getattr(itup,							  key->sk_attno,							  tupdesc,							  &isNull);		/* assume sk_func is strict */		if (isNull)			return false;		if (key->sk_flags & SK_ISNULL)			return false;		test = FunctionCall2(&key->sk_func, datum, key->sk_argument);		if (!DatumGetBool(test))			return false;		key++;		scanKeySize--;	}	return true;}/* * _hash_datum2hashkey -- given a Datum, call the index's hash procedure * * The Datum is assumed to be of the index's column type, so we can use the * "primary" hash procedure that's tracked for us by the generic index code. */uint32_hash_datum2hashkey(Relation rel, Datum key){	FmgrInfo   *procinfo;	/* XXX assumes index has only one attribute */	procinfo = index_getprocinfo(rel, 1, HASHPROC);	return DatumGetUInt32(FunctionCall1(procinfo, key));}/* * _hash_datum2hashkey_type -- given a Datum of a specified type, *			hash it in a fashion compatible with this index * * This is much more expensive than _hash_datum2hashkey, so use it only in * cross-type situations. */uint32_hash_datum2hashkey_type(Relation rel, Datum key, Oid keytype){	RegProcedure hash_proc;	/* XXX assumes index has only one attribute */	hash_proc = get_opfamily_proc(rel->rd_opfamily[0],								  keytype,								  keytype,								  HASHPROC);	if (!RegProcedureIsValid(hash_proc))		elog(ERROR, "missing support function %d(%u,%u) for index \"%s\"",			 HASHPROC, keytype, keytype,			 RelationGetRelationName(rel));	return DatumGetUInt32(OidFunctionCall1(hash_proc, key));}/* * _hash_hashkey2bucket -- determine which bucket the hashkey maps to. */Bucket_hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket,					 uint32 highmask, uint32 lowmask){	Bucket		bucket;	bucket = hashkey & highmask;	if (bucket > maxbucket)		bucket = bucket & lowmask;	return bucket;}/* * _hash_log2 -- returns ceil(lg2(num)) */uint32_hash_log2(uint32 num){	uint32		i,				limit;	limit = 1;	for (i = 0; limit < num; limit <<= 1, i++)		;	return i;}/* * _hash_checkpage -- sanity checks on the format of all hash pages * * If flags is not zero, it is a bitwise OR of the acceptable values of * hasho_flag. */void_hash_checkpage(Relation rel, Buffer buf, int flags){	Page		page = BufferGetPage(buf);	/*	 * ReadBuffer verifies that every newly-read page passes	 * PageHeaderIsValid, which means it either contains a reasonably sane	 * page header or is all-zero.	We have to defend against the all-zero	 * case, however.	 */	if (PageIsNew(page))		ereport(ERROR,				(errcode(ERRCODE_INDEX_CORRUPTED),			 errmsg("index \"%s\" contains unexpected zero page at block %u",					RelationGetRelationName(rel),					BufferGetBlockNumber(buf)),				 errhint("Please REINDEX it.")));	/*	 * Additionally check that the special area looks sane.	 */	if (((PageHeader) (page))->pd_special !=		(BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))		ereport(ERROR,				(errcode(ERRCODE_INDEX_CORRUPTED),				 errmsg("index \"%s\" contains corrupted page at block %u",						RelationGetRelationName(rel),						BufferGetBlockNumber(buf)),				 errhint("Please REINDEX it.")));	if (flags)	{		HashPageOpaque opaque = (HashPageOpaque) PageGetSpecialPointer(page);		if ((opaque->hasho_flag & flags) == 0)			ereport(ERROR,					(errcode(ERRCODE_INDEX_CORRUPTED),				   errmsg("index \"%s\" contains corrupted page at block %u",						  RelationGetRelationName(rel),						  BufferGetBlockNumber(buf)),					 errhint("Please REINDEX it.")));	}	/*	 * When checking the metapage, also verify magic number and version.	 */	if (flags == LH_META_PAGE)	{		HashMetaPage metap = (HashMetaPage) page;		if (metap->hashm_magic != HASH_MAGIC)			ereport(ERROR,					(errcode(ERRCODE_INDEX_CORRUPTED),					 errmsg("index \"%s\" is not a hash index",							RelationGetRelationName(rel))));		if (metap->hashm_version != HASH_VERSION)			ereport(ERROR,					(errcode(ERRCODE_INDEX_CORRUPTED),					 errmsg("index \"%s\" has wrong hash version",							RelationGetRelationName(rel)),					 errhint("Please REINDEX it.")));	}}Datumhashoptions(PG_FUNCTION_ARGS){	Datum		reloptions = PG_GETARG_DATUM(0);	bool		validate = PG_GETARG_BOOL(1);	bytea	   *result;	result = default_reloptions(reloptions, validate,								HASH_MIN_FILLFACTOR,								HASH_DEFAULT_FILLFACTOR);	if (result)		PG_RETURN_BYTEA_P(result);	PG_RETURN_NULL();}

⌨️ 快捷键说明

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