/* * statext_ndistinct_build * Compute ndistinct coefficient for the combination of attributes. * * This computes the ndistinct estimate using the same estimator used * in analyze.c and then computes the coefficient. */ MVNDistinct * statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows, Bitmapset *attrs, VacAttrStats **stats) { MVNDistinct *result; int k; int itemcnt; int numattrs = bms_num_members(attrs); int numcombs = num_combinations(numattrs); result = palloc(offsetof(MVNDistinct, items) + numcombs * sizeof(MVNDistinctItem)); result->magic = STATS_NDISTINCT_MAGIC; result->type = STATS_NDISTINCT_TYPE_BASIC; result->nitems = numcombs; itemcnt = 0; for (k = 2; k <= numattrs; k++) { int *combination; CombinationGenerator *generator; /* generate combinations of K out of N elements */ generator = generator_init(numattrs, k); while ((combination = generator_next(generator))) { MVNDistinctItem *item = &result->items[itemcnt]; int j; item->attrs = NULL; for (j = 0; j < k; j++) item->attrs = bms_add_member(item->attrs, stats[combination[j]]->attr->attnum); item->ndistinct = ndistinct_for_combination(totalrows, numrows, rows, stats, k, combination); itemcnt++; Assert(itemcnt <= result->nitems); } generator_free(generator); } /* must consume exactly the whole output array */ Assert(itemcnt == result->nitems); return result; }
void field_free(field_t * field) { if (field) { switch (field->type) { case TYPE_STRING: free(field->value.string); break; case TYPE_GENERATOR: generator_free(field->value.generator); break; default: break; } free(field); } }
static void generator_add_digger_test(void) { struct dungeon *dungeon = dungeon_alloc(); struct dungeon_options *dungeon_options = dungeon_options_alloc_default(); struct generator *generator = generator_alloc(dungeon, global_rnd, dungeon_options, NULL, NULL); assert(0 == generator->diggers_count); struct digger *digger1 = generator_add_digger(generator, point_make(1, 1, 1), direction_north); assert(1 == generator->diggers_count); generator_delete_digger(generator, digger1); assert(0 == generator->diggers_count); digger1 = generator_add_digger(generator, point_make(1, 1, 1), direction_north); assert(1 == generator->diggers_count); struct digger *digger2 = generator_add_digger(generator, point_make(2, 2, 2), direction_north); assert(2 == generator->diggers_count); struct digger *digger3 = generator_add_digger(generator, point_make(3, 3, 3), direction_north); assert(3 == generator->diggers_count); generator_delete_digger(generator, digger2); assert(2 == generator->diggers_count); assert(digger1 == generator->diggers[0]); assert(digger3 == generator->diggers[1]); generator_delete_digger(generator, digger1); assert(1 == generator->diggers_count); assert(digger3 == generator->diggers[0]); generator_free(generator); dungeon_options_free(dungeon_options); dungeon_free(dungeon); }
int main(int argc, char **argv) { Generator *gen; int r = 0; srand(0xdecade); /* make tests reproducible */ gen = generator_new(); if (argc == 1) { test_basic_set(gen); } else if (argc == 2) { test_specific_type(gen, argv[1]); } else { fprintf(stderr, "usage: %s [number/type]\n", program_invocation_short_name); r = 77; } generator_free(gen); return r; }
void field_free(field_t * field) { if (field) { switch (field->type) { case TYPE_STRING: free(field->value.string); break; case TYPE_GENERATOR: generator_free(field->value.generator); break; #ifdef USE_BITS case TYPE_BITS: free(field->value.bits.bits); break; #endif default: break; } free(field); } }