/** * @brief Destroys a bitset data structure that was created by bitset_new. * @details Destroys the set and then releases its memory. * @param set Pointer to an initialized bitset data structure. */ void bitset_free(bitset_t *set) { #ifdef BITSET_ASSERTIONS assert(set); #endif bitset_destroy(set); if(set) free(set); }
/** * \brief Free internal elements of a group * \warning The structure itself is not freed * \param[in,out] grp Pointer to the group */ static void group_deinit(struct pevents_group *grp) { if (grp->all_ptr != NULL) { // Delete items for (size_t i = 0; i < grp->all_size; ++i) { free(grp->all_ptr[i]); } } free(grp->all_ptr); bitset_destroy(grp->bitset); }
static void test_cardinality() { header(); struct bitset bm; bitset_create(&bm, realloc); fail_unless(bitset_cardinality(&bm) == 0); size_t cnt = 0; fail_if(bitset_set(&bm, 10) < 0); cnt++; fail_if(bitset_set(&bm, 15) < 0); cnt++; fail_if(bitset_set(&bm, 20) < 0); cnt++; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_set(&bm, 10) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 20) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 20) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 666) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 10) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 15) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); bitset_destroy(&bm); footer(); }
/* Make an estimate of the total cost of determining the given condition * with the given set of still-needed variables. Return true on success, * and then also set soln_mincost with the cost of running all generators * and the condition, and set soln_generators (which must be allocated) * to the set of generators used to get to this point. */ bool DEPRECATED_cnd_estimate_total_cost (struct condition *cc, bitset_t *varsneeded, float *soln_mincost, bitset_t *soln_generators) { // // First, for all varsneeded, determine their cheapest generator // struct iter_var_gen ivg; ivg.okay = true; ivg.vartab = cc->vartab; ivg.total_cost = cc->weight; ivg.varneed = bitset_clone (varsneeded); ivg.generate = soln_generators; bitset_empty (ivg.generate); bitset_iterate (varsneeded, var_cheap_generator_it, &ivg); bitset_destroy (ivg.varneed); *soln_mincost = ivg.total_cost; return ivg.okay; }
void bitset_index_destroy(struct bitset_index *index) { assert(index != NULL); assert(index->capacity > 0); for (size_t b = 0; b < index->capacity; b++) { if (index->bitsets[b] == NULL) break; bitset_destroy(index->bitsets[b]); index->realloc(index->bitsets[b], 0); index->bitsets[b] = NULL; } if (index->capacity > 0) { index->realloc(index->bitsets, 0); index->realloc(index->rollback_buf, 0); } memset(index, 0, sizeof(*index)); }
void set2_reduce_strong(lts_t lts){ int *map,count,*newmap,i,*tmp,iter,setcount,j,set; bitset_t has_repr; has_repr=bitset_create(8,16); lts_uniq(lts); lts_sort(lts); lts_set_type(lts,LTS_BLOCK); map=(int*)malloc(sizeof(int)*lts->states); newmap=(int*)malloc(sizeof(int)*lts->states); if (!map || !newmap || !has_repr) Fatal(1,1,"out of memory"); for(i=0;i<lts->states;i++){ map[i]=0; } count=1; iter=0; for(;;){ SetClear(-1); iter++; setcount=0; for(i=0;i<lts->states;i++){ set=EMPTY_SET; for(j=lts->begin[i];j<lts->begin[i+1];j++){ set=SetInsert(set,lts->label[j],map[lts->dest[j]]); } newmap[i]=set; if (!bitset_test(has_repr,set)){ bitset_set(has_repr,set); setcount++; } } Warning(2,"count is %d",setcount); if(count==setcount) break; bitset_clear_all(has_repr); count=setcount; tmp=map; map=newmap; newmap=tmp; } setcount=0; for(i=0;i<lts->states;i++){ newmap[i]=SetGetTag(map[i]); if (newmap[i]<0) { SetSetTag(map[i],setcount); newmap[i]=setcount; setcount++; } } free(map); map=newmap; Warning(2,"final count is %d",setcount); SetFree(); lts_set_type(lts,LTS_LIST); lts->root=map[lts->root]; lts->root2=map[lts->root2]; for(i=0;i<lts->transitions;i++){ lts->src[i]=map[lts->src[i]]; lts->dest[i]=map[lts->dest[i]]; } lts->states=count; lts_uniq(lts); free(map); bitset_destroy(has_repr); Warning(1,"reduction took %d iterations",iter); }
static void setclear(){ int i; bitset_t set=bitset_create(16,16); printf("setting 5 and 60\n"); bitset_set(set,5); bitset_set(set,60); for(i=0;i<80;i++) printf("%s",bitset_test(set,i)?"1":"0"); printf("\n"); int N=10; printf("%d in set is %d\n",N,bitset_test(set,N)); printf("set %d\n",N); bitset_set(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("clear %d\n",N); bitset_clear(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); N=100; printf("%d in set is %d\n",N,bitset_test(set,N)); printf("set %d\n",N); bitset_set(set,N); printf("%d in set is %d\n",10,bitset_test(set,10)); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("clear %d\n",N); bitset_clear(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); N=200; printf("%d in set is %d\n",N,bitset_test(set,N)); bitset_fprint(stdout,set); printf("set %d\n",N); bitset_set(set,N); bitset_fprint(stdout,set); printf("%d in set is %d\n",10,bitset_test(set,10)); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("clear %d\n",N); bitset_clear(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); bitset_fprint(stdout,set); printf("\n"); N=1000000; printf("%d in set is %d\n",N,bitset_test(set,N)); printf("set %d\n",N); bitset_set(set,N); printf("%d in set is %d\n",10,bitset_test(set,10)); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("clear %d\n",N); bitset_clear(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); N=10000; printf("%d in set is %d\n",N,bitset_test(set,N)); printf("set %d\n",N); bitset_set(set,N); printf("%d in set is %d\n",10,bitset_test(set,10)); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("clear %d\n",N); bitset_clear(set,N); printf("%d in set is %d\n",N,bitset_test(set,N)); printf("setting 5 and 60\n"); bitset_set(set,5); bitset_set(set,60); for(i=0;i<80;i++) printf("%s",bitset_test(set,i)?"1":"0"); printf("\n"); N=1222333; printf("set %d\n",N); bitset_set(set,N); printf("set:{"); for(element_t e=0;bitset_next_set(set,&e);e++){ printf(" %u",e); } printf(" }\n"); bitset_destroy(set); }
/* This is a complex, recursive function to determine the cost for * calculating a condition after any still-needed variables have been * generated. Cost is measured in terms of the anticipated number of * generated new variable sets, as provided by "*float" annotations * on generator and condition lines. * * Call this with a condition and varsneeded. The soln_xxx fields will * be filled with the requested information, namely the total cost * and the generators needed to get there. The soln_generators bitset * is assumed to already exist. * * This function may not always be able to determine a solution; this * can be the case if variables are mentioned in conditions but not in * generators, for instance. In such situations, the function returns * false. It is considered a success if all variables that are needed * for a condition are resolved by at least one generator. * * This is an important function when determining the "path of least * resistence" from any generator activity; the least costly condition * will always be calculated first, then the calculations are redone, * and what is then the least will be selected, and so on. The * generators required will be inserted into the path before their * dependent conditions, in the order of least-costly ones first. * * This is a rather heavy form of analysis, but it is executed only * once, at startup of the environment. After that, the SyncRepl * updates can ripple through in great speed. Note that the complexity * and time delays of these procedures rise with the (usually modest) * degree of interrelationships between generators and conditions. */ bool cnd_get_min_total_cost (struct condition *cc, bitset_t *varsneeded, float *soln_mincost, bitset_t *soln_generators) { bool have_soln = false; float soln_mincost; varnum_t v, v_max; gennum_t g, g_max; // // Allocate bitsets that will be used while cycling, but not // across recursive uses. To that and, a pile or pool of // bitsets could come in handy... TODO: Optimisation // bitset_t *cand_varsneeded = bitset_new (varsneeded->type); bitset_t *cand_generators = bitset_new (soln_generators->type); // // If there is no need for further variables to calculate this // condition, then terminate recursion on this function. There // will be no requirement to include a generator, and so there // will be no generator-incurred expenses. There will only be // the cost of the condition itself, which must still compare // with other conditions that might be tighter. // if (bitset_isempty (varsneeded)) { /* Recursion ends, so neither generators nor their cost */ bitset_empty (out_generators); return cc->cost; } // // Iterate over the variables that will need to be generated. // For each, iterate over the generators producing it. // See how this reduces the variable need, and recurse. // v_max = bitset_max (varsneeded); for (v=0; v<v_max; v++) { // // Skip this loop iteration if v is not actually needed. // if (!bitset_test (varsneeded, v)) { continue; } // // Iterate over generators for this variable. // Note that there may be none left? // bitset_t *vargenerators; vargenerators = var_share_generators (cc->vartab, v); g_max = bitset_max (vargenerators); if (g_max = BITNUM_BAD) { // Apparently, there are no generators for v // Skip for-loop (and trouble looping to BITNUM_BAD). continue; } for (g=0; g<g_max; g++) { bitset_t *cand_generators = NULL; bitset_t *generatorvars; float cand_cost; // // Reduce the variable need. // cand_varsneeded = bitset_copy (varsneeded); generatorvars = gen_share_variables (v); bitset_subtract (cand_varsneeded, generatorvars); // // Determine the cost for generating the remainder. // if (!cnd_get_cost_total ( cc, cand_varsneeded, &cand_cost, cand_generators)) { continue; } cand_mincost *= generator_cost (g); if (have_soln && (cand_cost > soln_mincost)) { continue; } tmp_generators = soln_generators; soln_generators = cand_generators; cand_generators = tmp_generators; // Reuse in loops bitset_set (soln_generators, g); soln_mincost = cand_mincost; have_soln = true; } } // // Cleanup temporary allocations. // bitset_destroy (cand_varsneeded); bitset_destroy (cand_generators); // // Collect results. Return success only if we do indeed have // found a solution. // return have_soln; }
static void test_get_set() { header(); struct bitset bm; bitset_create(&bm, realloc); const size_t NUM_SIZE = (size_t) 1 << 14; size_t *nums = malloc(NUM_SIZE * sizeof(size_t)); printf("Generating test set... "); for(size_t i = 0; i < NUM_SIZE; i++) { nums[i] = rand(); } printf("ok\n"); printf("Settings bits... "); for(size_t i = 0; i < NUM_SIZE; i++) { fail_if(bitset_set(&bm, nums[i]) < 0); } printf("ok\n"); printf("Checking bits... "); shuffle(nums, NUM_SIZE); for(size_t i = 0; i < NUM_SIZE; i++) { fail_unless(bitset_test(&bm, nums[i])); } printf("ok\n"); printf("Unsetting random bits... "); shuffle(nums, NUM_SIZE); for(size_t i = 0; i < NUM_SIZE; i++) { if (nums[i] % 5 == 0) { fail_if(bitset_clear(&bm, nums[i]) < 0); // printf("Clear :%zu\n", nums[i]); fail_if(bitset_test(&bm, nums[i])); } } printf("ok\n"); printf("Checking set bits... "); shuffle(nums, NUM_SIZE); for(size_t i = 0; i < NUM_SIZE; i++) { if (nums[i] % 5 == 0) { continue; } if (!bitset_test(&bm, nums[i])) { printf("Fail :%zu\n", nums[i]); } fail_unless(bitset_test(&bm, nums[i])); } printf("ok\n"); printf("Checking all bits... "); qsort(nums, NUM_SIZE, sizeof(size_t), size_compator); size_t *pn = nums; size_t i_max = (size_t) 1 << 14; if (i_max > RAND_MAX) { i_max = RAND_MAX; } for(size_t i = 0; i < i_max; i++) { if (*pn < SIZE_MAX && *pn == i) { fail_unless(bitset_test(&bm, *pn)); pn++; } else { fail_if(bitset_test(&bm, i)); } } printf("ok\n"); printf("Unsetting all bits... "); shuffle(nums, NUM_SIZE); for(size_t i = 0; i < NUM_SIZE; i++) { if (nums[i] == SIZE_MAX) { continue; } fail_if(bitset_clear(&bm, nums[i]) < 0); } printf("ok\n"); printf("Checking all bits... "); for(size_t i = 0; i < i_max; i++) { fail_if(bitset_test(&bm, i)); } printf("ok\n"); free(nums); bitset_destroy(&bm); footer(); }