HOT successor_container fill_queue_recursive(group & g, successor_container const & successors_from_parent, size_t previous_activation_limit) { assert (g.has_synth_children()); typedef server_node_list::reverse_iterator r_iterator; successor_container successors(successors_from_parent); size_t children = g.child_count(); sequential_child_list sequential_children; sequential_children.reserve(g.child_synth_count); for (r_iterator it = g.child_nodes.rbegin(); it != g.child_nodes.rend(); ++it) { server_node & node = *it; if (node.is_synth()) { r_iterator end_of_node = it; --end_of_node; // one element behind the last std::size_t node_count = 1; // we fill the child nodes in reverse order to an array for(;;) { sequential_children.push_back(&*it); ++it; if (it == g.child_nodes.rend()) break; // we found the beginning of this group if (!it->is_synth()) break; // we hit a child group, later we may want to add it's nodes, too? ++node_count; } --it; // we iterated one element too far, so we need to go back to the previous element assert(sequential_children.size() == node_count); auto seq_it = sequential_children.rbegin(); int activation_limit = get_previous_activation_count(it, g.child_nodes.rend(), previous_activation_limit); thread_queue_item * q_item = q->allocate_queue_item(queue_node(std::move(queue_node_data(static_cast<abstract_synth*>(*seq_it++))), node_count), successors, activation_limit); queue_node & q_node = q_item->get_job(); // now we can add all nodes sequentially for(;seq_it != sequential_children.rend(); ++seq_it) q_node.add_node(static_cast<abstract_synth*>(*seq_it)); sequential_children.clear(); assert(q_node.size() == node_count); /* advance successor list */ successors = successor_container(1); successors[0] = q_item; if (activation_limit == 0) q->add_initially_runnable(q_item); children -= node_count; } else { abstract_group & grp = static_cast<abstract_group&>(node); if (grp.has_synth_children()) { int activation_limit = get_previous_activation_count(it, g.child_nodes.rend(), previous_activation_limit); successors = fill_queue_recursive(grp, successors, activation_limit); } children -= 1; } } assert(children == 0); return successors; }
void fill_queue(group & root_group) { if (root_group.has_synth_children()) fill_queue_recursive(root_group, successor_container(0), 0); }