Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
void
ipset_assignment_cut(struct ipset_assignment *assignment,
                     ipset_variable var)
{
    if (var < cork_array_size(&assignment->values)) {
        assignment->values.size = var;
    }
}
Esempio n. 5
0
/**
 * 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 {
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
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;
    }
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}