/* The number of elements bits needs to cover bit n, measured in bytes. */
#define BVEC_BYTES(n) (((n) / BVEC_BITS_BITS + 1) * BVEC_SIZEOF_BITS)
-struct bvector {
- unsigned long *bits;
- size_t maxsize;
- unsigned long tiny[2]; /* Default fixed-size storage for bits. */
-};
-
/* bvector_resize ensures the storage used for bits can cover bit
* newsize. It always increases the size of the storage used for bits,
* even if newsize would have been covered by the existing storage.
static void bvector_resize (bvector_t vec, size_t newsize);
bvector_t
-bvector_create (size_t init_size) {
+bvector_create (void) {
bvector_t vec;
- size_t bytes;
/* See "wider than unsigned long" comment above. */
assert (sizeof *vec->bits <= sizeof 1ul);
NEW(vec);
-
- if (init_size <= BVEC_INIT_SIZE) {
- vec->bits = vec->tiny;
- vec->maxsize = BVEC_INIT_SIZE;
- memset(vec->tiny, 0, sizeof vec->tiny);
- return vec;
- }
-
- bytes = BVEC_BYTES(init_size);
- vec->bits = mh_xcalloc (1, bytes);
- vec->maxsize = bytes * CHAR_BIT;
+ bvector_init(vec);
return vec;
}
+void bvector_init(struct bvector *bv)
+{
+ bv->bits = bv->tiny;
+ bv->maxsize = BVEC_INIT_SIZE;
+ memset(bv->tiny, 0, sizeof bv->tiny);
+}
+
void
bvector_copy (bvector_t dest, bvector_t src) {
size_t bytes = BVEC_BYTES(src->maxsize);
if (dest->bits != dest->tiny)
free(dest->bits);
- dest->bits = mh_xmalloc (bytes);
+ if (bytes <= sizeof dest->tiny)
+ dest->bits = dest->tiny;
+ else
+ dest->bits = mh_xmalloc (bytes);
memcpy (dest->bits, src->bits, bytes);
dest->maxsize = src->maxsize;
}
void
bvector_free (bvector_t vec) {
- if (vec->bits != vec->tiny)
- free(vec->bits);
+ bvector_fini(vec);
free (vec);
}
+void bvector_fini(struct bvector *bv)
+{
+ if (bv->bits != bv->tiny)
+ free(bv->bits);
+}
+
void
bvector_clear (bvector_t vec, size_t n) {
- size_t word = BVEC_WORD(n);
- size_t offset = BVEC_OFFSET(n);
-
- if (n >= vec->maxsize)
- bvector_resize (vec, n);
-
- vec->bits[word] &= ~(1ul << offset);
+ if (n < vec->maxsize)
+ vec->bits[BVEC_WORD(n)] &= ~(1ul << BVEC_OFFSET(n));
}
unsigned int
bvector_at (bvector_t vec, size_t i) {
- size_t word = BVEC_WORD(i);
- size_t offset = BVEC_OFFSET(i);
+ if (i < vec->maxsize)
+ return !!(vec->bits[BVEC_WORD(i)] & (1ul << BVEC_OFFSET(i)));
- return i < vec->maxsize
- ? (vec->bits[word] & (1ul << offset) ? 1 : 0)
- : 0;
+ return 0;
}
static void