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

📄 bitmapset.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Check extra words in a */	for (; i < a->nwords; i++)	{		if (a->words[i] != 0)			return true;	}	return false;}/* * bms_singleton_member - return the sole integer member of set * * Raises error if |a| is not 1. */intbms_singleton_member(const Bitmapset *a){	int			result = -1;	int			nwords;	int			wordnum;	if (a == NULL)		elog(ERROR, "bitmapset is empty");	nwords = a->nwords;	for (wordnum = 0; wordnum < nwords; wordnum++)	{		bitmapword	w = a->words[wordnum];		if (w != 0)		{			if (result >= 0 || HAS_MULTIPLE_ONES(w))				elog(ERROR, "bitmapset has multiple members");			result = wordnum * BITS_PER_BITMAPWORD;			while ((w & 255) == 0)			{				w >>= 8;				result += 8;			}			result += rightmost_one_pos[w & 255];		}	}	if (result < 0)		elog(ERROR, "bitmapset is empty");	return result;}/* * bms_num_members - count members of set */intbms_num_members(const Bitmapset *a){	int			result = 0;	int			nwords;	int			wordnum;	if (a == NULL)		return 0;	nwords = a->nwords;	for (wordnum = 0; wordnum < nwords; wordnum++)	{		bitmapword	w = a->words[wordnum];		/* we assume here that bitmapword is an unsigned type */		while (w != 0)		{			result += number_of_ones[w & 255];			w >>= 8;		}	}	return result;}/* * bms_membership - does a set have zero, one, or multiple members? * * This is faster than making an exact count with bms_num_members(). */BMS_Membershipbms_membership(const Bitmapset *a){	BMS_Membership result = BMS_EMPTY_SET;	int			nwords;	int			wordnum;	if (a == NULL)		return BMS_EMPTY_SET;	nwords = a->nwords;	for (wordnum = 0; wordnum < nwords; wordnum++)	{		bitmapword	w = a->words[wordnum];		if (w != 0)		{			if (result != BMS_EMPTY_SET || HAS_MULTIPLE_ONES(w))				return BMS_MULTIPLE;			result = BMS_SINGLETON;		}	}	return result;}/* * bms_is_empty - is a set empty? * * This is even faster than bms_membership(). */boolbms_is_empty(const Bitmapset *a){	int			nwords;	int			wordnum;	if (a == NULL)		return true;	nwords = a->nwords;	for (wordnum = 0; wordnum < nwords; wordnum++)	{		bitmapword	w = a->words[wordnum];		if (w != 0)			return false;	}	return true;}/* * These operations all "recycle" their non-const inputs, ie, either * return the modified input or pfree it if it can't hold the result. * * These should generally be used in the style * *		foo = bms_add_member(foo, x); *//* * bms_add_member - add a specified member to set * * Input set is modified or recycled! */Bitmapset *bms_add_member(Bitmapset *a, int x){	int			wordnum,				bitnum;	if (x < 0)		elog(ERROR, "negative bitmapset member not allowed");	if (a == NULL)		return bms_make_singleton(x);	wordnum = WORDNUM(x);	bitnum = BITNUM(x);	if (wordnum >= a->nwords)	{		/* Slow path: make a larger set and union the input set into it */		Bitmapset  *result;		int			nwords;		int			i;		result = bms_make_singleton(x);		nwords = a->nwords;		for (i = 0; i < nwords; i++)			result->words[i] |= a->words[i];		pfree(a);		return result;	}	/* Fast path: x fits in existing set */	a->words[wordnum] |= ((bitmapword) 1 << bitnum);	return a;}/* * bms_del_member - remove a specified member from set * * No error if x is not currently a member of set * * Input set is modified in-place! */Bitmapset *bms_del_member(Bitmapset *a, int x){	int			wordnum,				bitnum;	if (x < 0)		elog(ERROR, "negative bitmapset member not allowed");	if (a == NULL)		return NULL;	wordnum = WORDNUM(x);	bitnum = BITNUM(x);	if (wordnum < a->nwords)		a->words[wordnum] &= ~((bitmapword) 1 << bitnum);	return a;}/* * bms_add_members - like bms_union, but left input is recycled */Bitmapset *bms_add_members(Bitmapset *a, const Bitmapset *b){	Bitmapset  *result;	const Bitmapset *other;	int			otherlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return bms_copy(b);	if (b == NULL)		return a;	/* Identify shorter and longer input; copy the longer one if needed */	if (a->nwords < b->nwords)	{		result = bms_copy(b);		other = a;	}	else	{		result = a;		other = b;	}	/* And union the shorter input into the result */	otherlen = other->nwords;	for (i = 0; i < otherlen; i++)		result->words[i] |= other->words[i];	if (result != a)		pfree(a);	return result;}/* * bms_int_members - like bms_intersect, but left input is recycled */Bitmapset *bms_int_members(Bitmapset *a, const Bitmapset *b){	int			shortlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return NULL;	if (b == NULL)	{		pfree(a);		return NULL;	}	/* Intersect b into a; we need never copy */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)		a->words[i] &= b->words[i];	for (; i < a->nwords; i++)		a->words[i] = 0;	return a;}/* * bms_del_members - like bms_difference, but left input is recycled */Bitmapset *bms_del_members(Bitmapset *a, const Bitmapset *b){	int			shortlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return NULL;	if (b == NULL)		return a;	/* Remove b's bits from a; we need never copy */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)		a->words[i] &= ~b->words[i];	return a;}/* * bms_join - like bms_union, but *both* inputs are recycled */Bitmapset *bms_join(Bitmapset *a, Bitmapset *b){	Bitmapset  *result;	Bitmapset  *other;	int			otherlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return b;	if (b == NULL)		return a;	/* Identify shorter and longer input; use longer one as result */	if (a->nwords < b->nwords)	{		result = b;		other = a;	}	else	{		result = a;		other = b;	}	/* And union the shorter input into the result */	otherlen = other->nwords;	for (i = 0; i < otherlen; i++)		result->words[i] |= other->words[i];	if (other != result)		/* pure paranoia */		pfree(other);	return result;}/*---------- * bms_first_member - find and remove first member of a set * * Returns -1 if set is empty.	NB: set is destructively modified! * * This is intended as support for iterating through the members of a set. * The typical pattern is * *			tmpset = bms_copy(inputset); *			while ((x = bms_first_member(tmpset)) >= 0) *				process member x; *			bms_free(tmpset); *---------- */intbms_first_member(Bitmapset *a){	int			nwords;	int			wordnum;	if (a == NULL)		return -1;	nwords = a->nwords;	for (wordnum = 0; wordnum < nwords; wordnum++)	{		bitmapword	w = a->words[wordnum];		if (w != 0)		{			int			result;			w = RIGHTMOST_ONE(w);			a->words[wordnum] &= ~w;			result = wordnum * BITS_PER_BITMAPWORD;			while ((w & 255) == 0)			{				w >>= 8;				result += 8;			}			result += rightmost_one_pos[w & 255];			return result;		}	}	return -1;}/* * bms_hash_value - compute a hash key for a Bitmapset * * Note: we must ensure that any two bitmapsets that are bms_equal() will * hash to the same value; in practice this means that trailing all-zero * words cannot affect the result.	The circular-shift-and-XOR hash method * used here has this property, so long as we work from back to front. * * Note: you might wonder why we bother with the circular shift; at first * glance a straight longitudinal XOR seems as good and much simpler.  The * reason is empirical: this gives a better distribution of hash values on * the bitmapsets actually generated by the planner.  A common way to have * multiword bitmapsets is "a JOIN b JOIN c JOIN d ...", which gives rise * to rangetables in which base tables and JOIN nodes alternate; so * bitmapsets of base table RT indexes tend to use only odd-numbered or only * even-numbered bits.	A straight longitudinal XOR would preserve this * property, leading to a much smaller set of possible outputs than if * we include a shift. */uint32bms_hash_value(const Bitmapset *a){	bitmapword	result = 0;	int			wordnum;	if (a == NULL || a->nwords <= 0)		return 0;				/* All empty sets hash to 0 */	for (wordnum = a->nwords; --wordnum > 0;)	{		result ^= a->words[wordnum];		if (result & ((bitmapword) 1 << (BITS_PER_BITMAPWORD - 1)))			result = (result << 1) | 1;		else			result = (result << 1);	}	result ^= a->words[0];	return (uint32) result;}

⌨️ 快捷键说明

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