Example #1
0
/* 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.
 *
 * This cost estimator assumes that vartab_analyse_cheapest_generators()
 * has already been run, and it only succeeds when all varsneeded have
 * a generator assigned to them (which should be caught out by that prior
 * phase, but it nonetheless returns an OK as a boolean).
 *
 * The soln_mincost represents the minimum cost estimation for setting up
 * all the variables.  The soln_generators provides the generators that
 * need to run before the varsneeded have been generated, ordered by
 * ascending weight.  The soln_generator_count provides the number of
 * entries filled into this table; the assumption made is that at least
 * as many entries are available as the number of elements in varsneeded.
 * Room up to this point may be overwritten by this routine, even if this
 * exceeds the impression given by a lower soln_generator_count.
 */
bool cnd_estimate_total_cost (struct cndtab *cctab, cndnum_t cndnum,
				bitset_t *varsneeded,
				float *soln_mincost,
				struct gentab *gentab,
				unsigned int *soln_generator_count,
				gennum_t soln_generators []) {
	bitset_iter_t v;
	bitset_t *vneeded;
	*soln_generator_count = 0;
	//
	// Find the cheapest generator for each of the varsneeded
	bitset_iterator_init (&v, varsneeded);
	while (bitset_iterator_next_one (&v, NULL)) {
		gennum_t unit_gen;
		bitset_t *genvars;
		unsigned int gi = bitset_iterator_bitnum (&v);
		//
		// The first step generates a list with the cheapest generators;
		// this could actually return an ordered _list_ of generators
		// and would cut off the most expensive ones when varsneeded
		// are generated as by-products in other generators.
		// This leads to more accurate estimates, and more efficiency.
		if (!var_get_cheapest_generator (
					vartab_from_type (cctab->vartype),
					gi,
					&unit_gen, NULL)) {
			return false;
		}
		soln_generators [*soln_generator_count++] = unit_gen;
	}
	//
	// Now sort the soln_generators by their weight.
	//
	// This is a sort for optimisation purposes; if it returns an error,
	// then the cause is normally memory shortage, in which case the
	// lost efficiency here is less vital than other things going awry.
	QSORT_R(soln_generators,
			*soln_generator_count,
			sizeof (struct generator *),
			gentab,
			_qsort_gen_cmp_weight);
	//
	// From the sorted soln_generators list, subtract generated variables
	// from varsneeded until all are done.  Cut off the output list at
	// that point by returning a possibly lower soln_generator_count.
	//
	//TODO// Might be able to skip generators that add nothing of interest
	*soln_generator_count = 0;
	*soln_mincost = cnd_get_weight (cctab, cndnum);
	vneeded = bitset_clone (varsneeded);
	while (!bitset_isempty (vneeded)) {
		gennum_t g = soln_generators [*soln_generator_count++];
		*soln_mincost *= gen_get_weight (gentab, g);
		bitset_t *genvars = gen_share_variables (gentab, g);
		bitset_subtract (vneeded, genvars);
	}
	bitset_destroy (vneeded);
	return true;
}
Example #2
0
/* Based on the variables needed in each condition, partition the variables.
 * Initially, each variable is created within its own, size-1 partition.
 * Conditions that mention multiple variables however, pull variables together
 * into the same partition.  This is done by renumbering one partition to
 * another partition.
 */
static void cnd_drive_partitions (struct cndtab *tab, cndnum_t cndnum) {
	bitset_iter_t bi;
	varnum_t onevar, othvar;
	struct vartab *vartab;
	bitset_iterator_init (&bi, tab->cnds [cndnum].vars_needed);
	if (!bitset_iterator_next_one (&bi, NULL)) {
		return;
	}
	vartab = vartab_from_type (tab->vartype);
	onevar = bitset_iterator_bitnum (&bi);
	while (bitset_iterator_next_one (&bi, NULL)) {
		othvar = bitset_iterator_bitnum (&bi);
		vartab_merge_partitions (vartab, onevar, othvar);
	}
}
Example #3
0
int
bitset_index_init_iterator(struct bitset_index *index,
			   struct bitset_iterator *it, struct bitset_expr *expr)
{
	assert(index != NULL);
	assert(it != NULL);

	/* Check that we have all required bitsets */
	size_t max = 0;
	for (size_t c = 0; c < expr->size; c++) {
		for (size_t b = 0; b < expr->conjs[c].size; b++) {
			if (expr->conjs[c].bitset_ids[b] > max) {
				max = expr->conjs[c].bitset_ids[b];
			}
		}
	}

	/* Resize the index with empty bitsets */
	if (bitset_index_reserve(index, max + 1) != 0)
		return -1;

	return bitset_iterator_init(it, expr, index->bitsets, index->capacity);
}