struct vrt_consumer * vrt_consumer_new(const char *name, struct vrt_queue *q) { struct vrt_consumer *c = cork_new(struct vrt_consumer); memset(c, 0, sizeof(struct vrt_consumer)); c->name = cork_strdup(name); cork_array_init(&c->dependencies); ei_check(vrt_queue_add_consumer(q, c)); c->cursor.value = starting_value; c->last_available_id = starting_value; c->current_id = starting_value; c->eof_count = 0; c->batch_count = 0; c->yield_count = 0; return c; error: if (c->name != NULL) { cork_strfree(c->name); } cork_array_done(&c->dependencies); cork_delete(struct vrt_consumer, c); return NULL; }
struct ipset_assignment * ipset_assignment_new() { struct ipset_assignment *assignment = cork_new(struct ipset_assignment); cork_array_init(&assignment->values); return assignment; }
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; }
struct ipset_node_cache * ipset_node_cache_new() { struct ipset_node_cache *cache = cork_new(struct ipset_node_cache); cork_array_init(&cache->chunks); cache->largest_index = 0; cache->free_list = IPSET_NULL_INDEX; cache->node_cache = cork_hash_table_new(0, 0); cork_hash_table_set_hash (cache->node_cache, (cork_hash_f) ipset_node_hash); cork_hash_table_set_equals (cache->node_cache, (cork_equals_f) ipset_node_equals); return cache; }
struct ipset_bdd_iterator * ipset_node_iterate(struct ipset_node_cache *cache, ipset_node_id root) { /* First allocate the iterator itself, and all of its contained * fields. */ struct ipset_bdd_iterator *iterator = cork_new(struct ipset_bdd_iterator); iterator->finished = false; iterator->cache = cache; cork_array_init(&iterator->stack); iterator->assignment = ipset_assignment_new(); /* Then add the root node to the iterator, tracing down until we * find the first terminal node. */ add_node(iterator, root); return iterator; }