[dpdk-dev] [PATCH v4 05/29] graph: implement internal graph operation helpers
Andrzej Ostruszka
amo at semihalf.com
Tue Apr 7 14:16:38 CEST 2020
On 4/5/20 10:55 AM, jerinj at marvell.com wrote:
> From: Jerin Jacob <jerinj at marvell.com>
>
> Adding internal graph API helpers support to check whether a graph has
> isolated nodes and any node have a loop to itself and BFS
> algorithm implementation etc.
>
> Signed-off-by: Jerin Jacob <jerinj at marvell.com>
> Signed-off-by: Nithin Dabilpuram <ndabilpuram at marvell.com>
> ---
[...]> +/* Check whether a node has next_node to itself */
> +static inline int
> +node_has_loop_edge(struct node *node)
> +{
> + rte_edge_t i;
> + char *name;
> + int rc = 0;
> +
> + for (i = 0; i < node->nb_edges; i++) {
> + if (strncmp(node->name, node->next_nodes[i],
> + RTE_NODE_NAMESIZE) == 0) {
> + name = node->name;
> + rc = 1;
> + SET_ERR_JMP(EINVAL, fail, "Node %s has loop to self",
> + name);
> + }
> + }
> +fail:
> + return rc;
> +}
In general, I'd expect such warnings/errors to be at usage - this is
simple test and its job should be just return true/false. But in this
particular case I guess it is always an error (no cycles in graph
allowed) so I'm fine if you leave it here.
> +
> +int
> +graph_node_has_loop_edge(struct graph *graph)
> +{
> + struct graph_node *graph_node;
> +
> + STAILQ_FOREACH(graph_node, &graph->node_list, next)
> + if (node_has_loop_edge(graph_node->node))
> + return 1;
> +
> + return 0;
> +}
[...]
> +void
> +graph_mark_nodes_as_not_visited(struct graph *graph)
> +{
> + struct graph_node *graph_node;
> +
> + STAILQ_FOREACH(graph_node, &graph->node_list, next)
> + graph_node->visited = false;
> +}
> +
> +int
> +graph_bfs(struct graph *graph, struct graph_node *start)
> +{
> + struct graph_node **queue, *v, *tmp;
> + uint16_t head = 0, tail = 0;
> + rte_edge_t i;
> + size_t sz;
> +
> + sz = sizeof(struct graph_node *) * graph_nodes_count(graph);
> + queue = malloc(sz);
> + if (queue == NULL)
> + SET_ERR_JMP(ENOMEM, fail, "Failed to alloc BFS queue of %zu",
> + sz);
> +
> + /* BFS algorithm */
> + queue[tail++] = start;
> + start->visited = true;
> + while (head != tail) {
> + v = queue[head++];
> + for (i = 0; i < v->node->nb_edges; i++) {
> + tmp = v->adjacency_list[i];
> + if (tmp->visited == false) {
> + queue[tail++] = tmp;
> + tmp->visited = true;
> + }
> + }
> + }
> +
> + free(queue);
> + return 0;
> +
> +fail:
> + return -rte_errno;
> +}
What is the purpose of this function? It looks like just marking as
visited. Then maybe change the name to graph_mark_bfs() or something
like that.
> +
> +/* Check whether a node has connected path or parent node */
> +int
> +graph_has_isolated_node(struct graph *graph)
> +{
> + struct graph_node *graph_node;
> +
> + graph_mark_nodes_as_not_visited(graph);
> +
> + STAILQ_FOREACH(graph_node, &graph->node_list, next) {
> + if (graph_node->node->flags & RTE_NODE_SOURCE_F) {
> + if (graph_node->node->nb_edges == 0)
> + SET_ERR_JMP(EINVAL, fail,
> + "%s node needs minimum one edge",
> + graph_node->node->name);
> + if (graph_bfs(graph, graph_node))
> + goto fail;
> + }
> + }
> +
> + STAILQ_FOREACH(graph_node, &graph->node_list, next)
> + if (graph_node->visited == false)
> + SET_ERR_JMP(EINVAL, fail, "Found isolated node %s",
> + graph_node->node->name);> +
> + return 0;
You don't want to clear visited because it will not be used or cleared
on next call?
With regards
Andrzej Ostruszka
More information about the dev
mailing list