summaryrefslogtreecommitdiff
path: root/src/backend/nodes/bitmapset.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-11-28 14:16:24 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-11-28 14:16:24 -0500
commitd25367ec4f869aac80e97964fa5d7143536818b1 (patch)
treedbcc0102cdde5c0147622c3ff317444b0c711b3a /src/backend/nodes/bitmapset.c
parentf4e031c662a6b600b786c4849968a099c58fcce7 (diff)
downloadpostgresql-d25367ec4f869aac80e97964fa5d7143536818b1.tar.gz
Add bms_get_singleton_member(), and use it where appropriate.
This patch adds a function that replaces a bms_membership() test followed by a bms_singleton_member() call, performing both the test and the extraction of a singleton set's member in one scan of the bitmapset. The performance advantage over the old way is probably minimal in current usage, but it seems worthwhile on notational grounds anyway. David Rowley
Diffstat (limited to 'src/backend/nodes/bitmapset.c')
-rw-r--r--src/backend/nodes/bitmapset.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 26a0f872b3..c4e1d26a49 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -525,6 +525,50 @@ bms_singleton_member(const Bitmapset *a)
}
/*
+ * bms_get_singleton_member
+ *
+ * Test whether the given set is a singleton.
+ * If so, set *member to the value of its sole member, and return TRUE.
+ * If not, return FALSE, without changing *member.
+ *
+ * This is more convenient and faster than calling bms_membership() and then
+ * bms_singleton_member(), if we don't care about distinguishing empty sets
+ * from multiple-member sets.
+ */
+bool
+bms_get_singleton_member(const Bitmapset *a, int *member)
+{
+ int result = -1;
+ int nwords;
+ int wordnum;
+
+ if (a == NULL)
+ return false;
+ nwords = a->nwords;
+ for (wordnum = 0; wordnum < nwords; wordnum++)
+ {
+ bitmapword w = a->words[wordnum];
+
+ if (w != 0)
+ {
+ if (result >= 0 || HAS_MULTIPLE_ONES(w))
+ return false;
+ result = wordnum * BITS_PER_BITMAPWORD;
+ while ((w & 255) == 0)
+ {
+ w >>= 8;
+ result += 8;
+ }
+ result += rightmost_one_pos[w & 255];
+ }
+ }
+ if (result < 0)
+ return false;
+ *member = result;
+ return true;
+}
+
+/*
* bms_num_members - count members of set
*/
int