Ejemplo 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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
size_t
ipset_node_reachable_count(const struct ipset_node_cache *cache,
                           ipset_node_id node)
{
    /* Create a set to track when we've visited a given node. */
    struct cork_hash_table  *visited = cork_pointer_hash_table_new(0, 0);

    /* And a queue of nodes to check. */
    cork_array(ipset_node_id)  queue;
    cork_array_init(&queue);

    if (ipset_node_get_type(node) == IPSET_NONTERMINAL_NODE) {
        DEBUG("Adding node %u to queue", node);
        cork_array_append(&queue, node);
    }

    /* And somewhere to store the result. */
    size_t  node_count = 0;

    /* Check each node in turn. */
    while (!cork_array_is_empty(&queue)) {
        ipset_node_id  curr = cork_array_at(&queue, --queue.size);

        /* We don't have to do anything if this node is already in the
         * visited set. */
        if (cork_hash_table_get(visited, (void *) (uintptr_t) curr) == NULL) {
            DEBUG("Visiting node %u for the first time", curr);

            /* Add the node to the visited set. */
            cork_hash_table_put
                (visited, (void *) (uintptr_t) curr,
                 (void *) (uintptr_t) true, NULL, NULL, NULL);

            /* Increase the node count. */
            node_count++;

            /* And add the node's nonterminal children to the visit
             * queue. */
            struct ipset_node  *node =
                ipset_node_cache_get_nonterminal(cache, curr);

            if (ipset_node_get_type(node->low) == IPSET_NONTERMINAL_NODE) {
                DEBUG("Adding node %u to queue", node->low);
                cork_array_append(&queue, node->low);
            }

            if (ipset_node_get_type(node->high) == IPSET_NONTERMINAL_NODE) {
                DEBUG("Adding node %u to queue", node->high);
                cork_array_append(&queue, node->high);
            }
        }
    }

    /* Return the result, freeing everything before we go. */
    cork_hash_table_free(visited);
    cork_array_done(&queue);
    return node_count;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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;
    }
}
Ejemplo n.º 9
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);
}