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

📄 bitmapset.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * bitmapset.c *	  PostgreSQL generic bitmap set package * * A bitmap set can represent any set of nonnegative integers, although * it is mainly intended for sets where the maximum value is not large, * say at most a few hundred.  By convention, a NULL pointer is always * accepted by all operations to represent the empty set.  (But beware * that this is not the only representation of the empty set.  Use * bms_is_empty() in preference to testing for NULL.) * * * Copyright (c) 2003-2005, PostgreSQL Global Development Group * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/nodes/bitmapset.c,v 1.10 2005/10/15 02:49:18 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "nodes/bitmapset.h"#define WORDNUM(x)	((x) / BITS_PER_BITMAPWORD)#define BITNUM(x)	((x) % BITS_PER_BITMAPWORD)#define BITMAPSET_SIZE(nwords)	\	(offsetof(Bitmapset, words) + (nwords) * sizeof(bitmapword))/*---------- * This is a well-known cute trick for isolating the rightmost one-bit * in a word.  It assumes two's complement arithmetic.  Consider any * nonzero value, and focus attention on the rightmost one.  The value is * then something like *				xxxxxx10000 * where x's are unspecified bits.  The two's complement negative is formed * by inverting all the bits and adding one.  Inversion gives *				yyyyyy01111 * where each y is the inverse of the corresponding x.	Incrementing gives *				yyyyyy10000 * and then ANDing with the original value gives *				00000010000 * This works for all cases except original value = zero, where of course * we get zero. *---------- */#define RIGHTMOST_ONE(x) ((signedbitmapword) (x) & -((signedbitmapword) (x)))#define HAS_MULTIPLE_ONES(x)	((bitmapword) RIGHTMOST_ONE(x) != (x))/* * Lookup tables to avoid need for bit-by-bit groveling * * rightmost_one_pos[x] gives the bit number (0-7) of the rightmost one bit * in a nonzero byte value x.  The entry for x=0 is never used. * * number_of_ones[x] gives the number of one-bits (0-8) in a byte value x. * * We could make these tables larger and reduce the number of iterations * in the functions that use them, but bytewise shifts and masks are * especially fast on many machines, so working a byte at a time seems best. */static const uint8 rightmost_one_pos[256] = {	0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};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};/* * bms_copy - make a palloc'd copy of a bitmapset */Bitmapset *bms_copy(const Bitmapset *a){	Bitmapset  *result;	size_t		size;	if (a == NULL)		return NULL;	size = BITMAPSET_SIZE(a->nwords);	result = (Bitmapset *) palloc(size);	memcpy(result, a, size);	return result;}/* * bms_equal - are two bitmapsets equal? * * This is logical not physical equality; in particular, a NULL pointer will * be reported as equal to a palloc'd value containing no members. */boolbms_equal(const Bitmapset *a, const Bitmapset *b){	const Bitmapset *shorter;	const Bitmapset *longer;	int			shortlen;	int			longlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)	{		if (b == NULL)			return true;		return bms_is_empty(b);	}	else if (b == NULL)		return bms_is_empty(a);	/* Identify shorter and longer input */	if (a->nwords <= b->nwords)	{		shorter = a;		longer = b;	}	else	{		shorter = b;		longer = a;	}	/* And process */	shortlen = shorter->nwords;	for (i = 0; i < shortlen; i++)	{		if (shorter->words[i] != longer->words[i])			return false;	}	longlen = longer->nwords;	for (; i < longlen; i++)	{		if (longer->words[i] != 0)			return false;	}	return true;}/* * bms_make_singleton - build a bitmapset containing a single member */Bitmapset *bms_make_singleton(int x){	Bitmapset  *result;	int			wordnum,				bitnum;	if (x < 0)		elog(ERROR, "negative bitmapset member not allowed");	wordnum = WORDNUM(x);	bitnum = BITNUM(x);	result = (Bitmapset *) palloc0(BITMAPSET_SIZE(wordnum + 1));	result->nwords = wordnum + 1;	result->words[wordnum] = ((bitmapword) 1 << bitnum);	return result;}/* * bms_free - free a bitmapset * * Same as pfree except for allowing NULL input */voidbms_free(Bitmapset *a){	if (a)		pfree(a);}/* * These operations all make a freshly palloc'd result, * leaving their inputs untouched *//* * bms_union - set union */Bitmapset *bms_union(const 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 bms_copy(a);	/* Identify shorter and longer input; copy the longer one */	if (a->nwords <= b->nwords)	{		result = bms_copy(b);		other = a;	}	else	{		result = bms_copy(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];	return result;}/* * bms_intersect - set intersection */Bitmapset *bms_intersect(const Bitmapset *a, const Bitmapset *b){	Bitmapset  *result;	const Bitmapset *other;	int			resultlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL || b == NULL)		return NULL;	/* Identify shorter and longer input; copy the shorter one */	if (a->nwords <= b->nwords)	{		result = bms_copy(a);		other = b;	}	else	{		result = bms_copy(b);		other = a;	}	/* And intersect the longer input with the result */	resultlen = result->nwords;	for (i = 0; i < resultlen; i++)		result->words[i] &= other->words[i];	return result;}/* * bms_difference - set difference (ie, A without members of B) */Bitmapset *bms_difference(const Bitmapset *a, const Bitmapset *b){	Bitmapset  *result;	int			shortlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return NULL;	if (b == NULL)		return bms_copy(a);	/* Copy the left input */	result = bms_copy(a);	/* And remove b's bits from result */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)		result->words[i] &= ~b->words[i];	return result;}/* * bms_is_subset - is A a subset of B? */boolbms_is_subset(const Bitmapset *a, const Bitmapset *b){	int			shortlen;	int			longlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return true;			/* empty set is a subset of anything */	if (b == NULL)		return bms_is_empty(a);	/* Check common words */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)	{		if ((a->words[i] & ~b->words[i]) != 0)			return false;	}	/* Check extra words */	if (a->nwords > b->nwords)	{		longlen = a->nwords;		for (; i < longlen; i++)		{			if (a->words[i] != 0)				return false;		}	}	return true;}/* * bms_is_member - is X a member of A? */boolbms_is_member(int x, const Bitmapset *a){	int			wordnum,				bitnum;	/* XXX better to just return false for x<0 ? */	if (x < 0)		elog(ERROR, "negative bitmapset member not allowed");	if (a == NULL)		return false;	wordnum = WORDNUM(x);	bitnum = BITNUM(x);	if (wordnum >= a->nwords)		return false;	if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)		return true;	return false;}/* * bms_overlap - do sets overlap (ie, have a nonempty intersection)? */boolbms_overlap(const Bitmapset *a, const Bitmapset *b){	int			shortlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL || b == NULL)		return false;	/* Check words in common */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)	{		if ((a->words[i] & b->words[i]) != 0)			return true;	}	return false;}/* * bms_nonempty_difference - do sets have a nonempty difference? */boolbms_nonempty_difference(const Bitmapset *a, const Bitmapset *b){	int			shortlen;	int			i;	/* Handle cases where either input is NULL */	if (a == NULL)		return false;	if (b == NULL)		return !bms_is_empty(a);	/* Check words in common */	shortlen = Min(a->nwords, b->nwords);	for (i = 0; i < shortlen; i++)	{		if ((a->words[i] & ~b->words[i]) != 0)			return true;	}

⌨️ 快捷键说明

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