/* Implementation of sets. (c) 1995 Paul Bagyenda.*/ #ifdef WN1_6 #include #include #include #include "setutil.h" typedef unsigned int bucket_t; struct set_tag { unsigned max_elem; bucket_t buckets[1]; }; #define BUCKET_SIZE (sizeof (bucket_t)) #define BITS_PER_BUCKET (8*BUCKET_SIZE) #define NBUCKETS(n) (((n) + BITS_PER_BUCKET - 1)/BITS_PER_BUCKET) /*create and initialise a set object that can hold up to max distinct objs*/ Set_t set_create(unsigned max_elem) { Set_t s = calloc(1, sizeof *s + (NBUCKETS(max_elem) - 1)*BUCKET_SIZE); assert(s); s->max_elem = max_elem; return s; } Set_t set_resize(Set_t s, unsigned new_max_elem) { unsigned n, m; assert(s); n = NBUCKETS(s->max_elem); m = NBUCKETS(new_max_elem); if (m != n) { s = realloc(s, sizeof *s + m*BUCKET_SIZE); assert(s); if (m > n) memset(s->buckets + n, 0, (m - n)*BUCKET_SIZE); } s->max_elem = new_max_elem; return s; } void set_destroy(Set_t s) { assert(s); free(s); } void set_addobj(Set_t s, unsigned objnum) { assert(s); assert(objnum < s->max_elem); s->buckets[objnum/BITS_PER_BUCKET] |= 1 << (objnum % BITS_PER_BUCKET); } void removeobj(Set_t s, unsigned objnum) { assert(s); assert(objnum < s->max_elem); s->buckets[objnum/BITS_PER_BUCKET] &= ~(1 << (objnum % BITS_PER_BUCKET)); } void set_union(Set_t u, Set_t a, Set_t b) { unsigned i; assert(a); assert(b); assert(u); assert(a->max_elem == b->max_elem); assert(u->max_elem >= a->max_elem); for (i = 0; i < NBUCKETS(a->max_elem); i++) u->buckets[i] = a->buckets[i] | b->buckets[i]; for ( ; i < NBUCKETS(u->max_elem); i++) u->buckets[i] = 0; } void set_intersection(Set_t n, Set_t a, Set_t b) { unsigned i; assert(a); assert(b); assert(n); assert(a->max_elem == b->max_elem); assert(n->max_elem >= a->max_elem); for (i = 0; i < NBUCKETS(a->max_elem); i++) n->buckets[i] = a->buckets[i] & b->buckets[i]; for ( ; i < NBUCKETS(n->max_elem); i++) n->buckets[i] = 0; } static int bitcount(bucket_t n) { int i, count; for (count = 0, i = 0; i < BITS_PER_BUCKET - 1; i++) if (n & (1 << i)) count++; return count; } int set_nelem(Set_t s) { unsigned i, n; assert(s); for (i = 0, n = 0; i < NBUCKETS(s->max_elem); i++) n += bitcount(s->buckets[i]); return n; } int set_isempty(Set_t s) { int i; assert(s); for (i = 0; i < NBUCKETS(s->max_elem); i++) if (s->buckets[i]) return 0; return 1; } int set_haselem(Set_t s, unsigned objnum) { assert(s); assert(objnum < s->max_elem); return s->buckets[objnum/BITS_PER_BUCKET] & (1 << (objnum % BITS_PER_BUCKET)); } int set_maxelem(Set_t s) { assert(s); return s->max_elem; } #endif