#ifndef LIGHTNING_PLUGINS_ASKRENE_CHILD_GRAPH_H
#define LIGHTNING_PLUGINS_ASKRENE_CHILD_GRAPH_H
#include "config.h"
#include <assert.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#define INVALID_INDEX 0xffffffff
struct arc {
u32 idx;
};
struct node {
u32 idx;
};
static inline struct arc arc_obj(u32 index)
{
struct arc arc = {.idx = index};
return arc;
}
static inline struct node node_obj(u32 index)
{
struct node node = {.idx = index};
return node;
}
struct graph {
struct node *arc_tail;
struct arc *node_adjacency_next;
struct arc *node_adjacency_first;
size_t max_num_arcs, max_num_nodes;
size_t arc_dual_bit;
};
static inline size_t graph_max_num_arcs(const struct graph *graph)
{
return graph->max_num_arcs;
}
static inline size_t graph_max_num_nodes(const struct graph *graph)
{
return graph->max_num_nodes;
}
static inline struct arc arc_dual(const struct graph *graph, struct arc arc)
{
arc.idx ^= (1U << graph->arc_dual_bit);
return arc;
}
static inline bool arc_is_dual(const struct graph *graph, struct arc arc)
{
return (arc.idx & (1U << graph->arc_dual_bit)) != 0;
}
static inline struct node arc_tail(const struct graph *graph,
const struct arc arc)
{
assert(arc.idx < graph_max_num_arcs(graph));
return graph->arc_tail[arc.idx];
}
static inline struct node arc_head(const struct graph *graph,
const struct arc arc)
{
const struct arc dual = arc_dual(graph, arc);
assert(dual.idx < graph_max_num_arcs(graph));
return graph->arc_tail[dual.idx];
}
static inline bool arc_enabled(const struct graph *graph, const struct arc arc)
{
return graph->arc_tail[arc.idx].idx < graph->max_num_nodes;
}
static inline struct arc node_adjacency_begin(const struct graph *graph,
const struct node node)
{
assert(node.idx < graph_max_num_nodes(graph));
return graph->node_adjacency_first[node.idx];
}
static inline bool node_adjacency_end(const struct arc arc)
{
return arc.idx == INVALID_INDEX;
}
static inline struct arc node_adjacency_next(const struct graph *graph,
const struct arc arc)
{
assert(arc.idx < graph_max_num_arcs(graph));
return graph->node_adjacency_next[arc.idx];
}
static inline struct arc node_rev_adjacency_begin(const struct graph *graph,
const struct node node)
{
return arc_dual(graph, node_adjacency_begin(graph, node));
}
static inline bool node_rev_adjacency_end(const struct arc arc)
{
return arc.idx == INVALID_INDEX;
}
static inline struct arc node_rev_adjacency_next(const struct graph *graph,
const struct arc arc)
{
return arc_dual(graph,
node_adjacency_next(graph, arc_dual(graph, arc)));
}
bool graph_add_arc(struct graph *graph, const struct arc arc,
const struct node from, const struct node to);
struct graph *graph_new(const tal_t *ctx, const size_t max_num_nodes,
const size_t max_num_arcs, const size_t arc_dual_bit);
#endif