📄 bitmapset.c
字号:
* 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; } /* 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -