void ipset_assignment_set(struct ipset_assignment *assignment, ipset_variable var, enum ipset_tribool value) { /* Ensure that the vector is big enough to hold this variable * assignment, inserting new EITHERs if needed. */ if (var >= cork_array_size(&assignment->values)) { unsigned int old_len = cork_array_size(&assignment->values); /* Expand the array. */ cork_array_ensure_size(&assignment->values, var+1); assignment->values.size = var+1; /* Fill in EITHERs in the newly allocated elements. */ if (var != old_len) { unsigned int i; for (i = old_len; i < var; i++) { cork_array_at(&assignment->values, i) = IPSET_EITHER; } } } /* Assign the desired value. */ cork_array_at(&assignment->values, var) = value; }
void ipset_bdd_iterator_advance(struct ipset_bdd_iterator *iterator) { /* If we're already at the end of the iterator, don't do anything. */ if (CORK_UNLIKELY(iterator->finished)) { return; } /* We look at the last node in the stack. If it's currently * assigned a false value, then we track down its true branch. If * it's got a true branch, then we pop it off and check the next to * last node. */ DEBUG("Advancing BDD iterator"); while (cork_array_size(&iterator->stack) > 0) { ipset_node_id last_node_id = cork_array_at (&iterator->stack, cork_array_size(&iterator->stack) - 1); struct ipset_node *last_node = ipset_node_cache_get_nonterminal(iterator->cache, last_node_id); enum ipset_tribool current_value = ipset_assignment_get(iterator->assignment, last_node->variable); /* The current value can't be EITHER, because we definitely * assign a TRUE or FALSE to the variables of the nodes that we * encounter. */ if (current_value == IPSET_TRUE) { /* We've checked both outgoing edges for this node, so pop * it off and look at its parent. */ iterator->stack.size--; /* Before continuing, reset this node's variable to * indeterminate in the assignment. */ ipset_assignment_set (iterator->assignment, last_node->variable, IPSET_EITHER); } else { /* We've checked this node's low edge, but not its high * edge. Set the variable to TRUE in the assignment, and * add the high edge's node to the node stack. */ ipset_assignment_set (iterator->assignment, last_node->variable, IPSET_TRUE); add_node(iterator, last_node->high); return; } } /* If we fall through then we ran out of nodes to check. That means * the iterator is done! */ iterator->finished = true; }
static int vrt_queue_add_producer(struct vrt_queue *q, struct vrt_producer *p) { clog_debug("[%s] Add producer %s", q->name, p->name); /* Add the producer to the queue's array and assign its index. */ cork_array_append(&q->producers, p); p->queue = q; p->index = cork_array_size(&q->producers) - 1; /* Choose the right claim and publish implementations for this * producer. */ if (p->index == 0) { /* If this is the first producer, use faster claim and publish * methods that are optimized for the single-producer case. */ p->claim = vrt_claim_single_threaded; p->publish = vrt_publish_single_threaded; } else { /* Otherwise we need to use slower, but multiple-producer- * capable, implementations of claim and publish. */ p->claim = vrt_claim_multi_threaded; p->publish = vrt_publish_multi_threaded; /* If this is the second producer, then we need to update the * first producer to also use the slower implementations. */ if (p->index == 1) { struct vrt_producer *first = cork_array_at(&q->producers, 0); first->claim = vrt_claim_multi_threaded; first->publish = vrt_publish_multi_threaded; } } return 0; }
void ipset_assignment_cut(struct ipset_assignment *assignment, ipset_variable var) { if (var < cork_array_size(&assignment->values)) { assignment->values.size = var; } }
/** * Returns the index of a new ipset_node instance. */ static ipset_value ipset_node_cache_alloc_node(struct ipset_node_cache *cache) { if (cache->free_list == IPSET_NULL_INDEX) { /* Nothing in the free list; need to allocate a new node. */ ipset_value next_index = cache->largest_index++; ipset_value chunk_index = next_index >> IPSET_BDD_NODE_CACHE_BIT_SIZE; if (chunk_index >= cork_array_size(&cache->chunks)) { /* We've filled up all of the existing chunks, and need to * create a new one. */ DEBUG(" (allocating chunk %zu)", cork_array_size(&cache->chunks)); struct ipset_node *new_chunk = cork_calloc (IPSET_BDD_NODE_CACHE_SIZE, sizeof(struct ipset_node)); cork_array_append(&cache->chunks, new_chunk); } return next_index; } else {
bool ipset_assignment_equal(const struct ipset_assignment *assignment1, const struct ipset_assignment *assignment2) { /* Identical pointers are trivially equal. */ if (assignment1 == assignment2) { return true; } /* Otherwise we compare the assignments piecewise up through the end * of the smaller vector. */ unsigned int size1 = cork_array_size(&assignment1->values); unsigned int size2 = cork_array_size(&assignment2->values); unsigned int smaller_size = (size1 < size2)? size1: size2; unsigned int i; for (i = 0; i < smaller_size; i++) { if (cork_array_at(&assignment1->values, i) != cork_array_at(&assignment2->values, i)) { return false; } } /* If one of the assignment vectors is longer, any remaining * elements must be indeterminate. */ if (size1 > smaller_size) { for (i = smaller_size; i < size1; i++) { if (cork_array_at(&assignment1->values, i) != IPSET_EITHER) { return false; } } } if (size2 > smaller_size) { for (i = smaller_size; i < size2; i++) { if (cork_array_at(&assignment2->values, i) != IPSET_EITHER) { return false; } } } /* If we make it through all of that, the two assignments are equal. */ return true; }
void ipset_node_cache_free(struct ipset_node_cache *cache) { size_t i; for (i = 0; i < cork_array_size(&cache->chunks); i++) { free(cork_array_at(&cache->chunks, i)); } cork_array_done(&cache->chunks); cork_hash_table_free(cache->node_cache); free(cache); }
static int vrt_queue_add_consumer(struct vrt_queue *q, struct vrt_consumer *c) { clog_debug("[%s] Add consumer %s", q->name, c->name); /* Add the consumer to the queue's array and assign its index. */ cork_array_append(&q->consumers, c); c->queue = q; c->index = cork_array_size(&q->consumers) - 1; return 0; }
enum ipset_tribool ipset_assignment_get(struct ipset_assignment *assignment, ipset_variable var) { if (var < cork_array_size(&assignment->values)) { /* If the requested variable is in the range of the values * array, return whatever is stored there. */ return cork_array_at(&assignment->values, var); } else { /* Variables htat aren't in the values array are always EITHER. */ return IPSET_EITHER; } }
int vrt_consumer_next(struct vrt_consumer *c, struct vrt_value **value) { do { unsigned int producer_count; struct vrt_value *v; rii_check(vrt_consumer_next_raw(c->queue, c)); v = vrt_queue_get(c->queue, c->current_id); switch (v->special) { case VRT_VALUE_NONE: *value = v; return 0; case VRT_VALUE_EOF: producer_count = cork_array_size(&c->queue->producers); c->eof_count++; clog_debug("<%s> Detected EOF (%u of %u) at value %d", c->name, c->eof_count, producer_count, c->current_id); if (c->eof_count == producer_count) { /* We've run out of values that we know can been * processed. Notify the world how much we've * processed so far. */ clog_debug("<%s> Signal consumption of %d", c->name, c->current_id); vrt_consumer_set_cursor(c, c->current_id); return VRT_QUEUE_EOF; } else { /* There are other producers still producing values, * so we should repeat the loop to grab the next * value. */ break; } case VRT_VALUE_HOLE: /* Repeat the loop to grab the next value. */ break; case VRT_VALUE_FLUSH: /* Return the FLUSH control message. */ return VRT_QUEUE_FLUSH; default: cork_unreachable(); } } while (true); }
static vrt_value_id vrt_minimum_cursor(vrt_consumer_array *cs) { /* We know there's always at least one consumer */ unsigned int i; vrt_value_id minimum = vrt_consumer_get_cursor(cork_array_at(cs, 0)); for (i = 1; i < cork_array_size(cs); i++) { vrt_value_id id = vrt_consumer_get_cursor(cork_array_at(cs, i)); if (vrt_mod_lt(id, minimum)) { minimum = id; } } return minimum; }
static void execute(int argc, char **argv) { size_t i; bz_load_repositories(); satisfy_dependencies(&buzzy_install, argc, argv); for (i = 0; i < cork_array_size(&dep_packages); i++) { struct bz_package *package = cork_array_at(&dep_packages, i); ri_check_error(bz_package_install(package)); } free_dependencies(); bz_finalize_actions(); exit(EXIT_SUCCESS); }