X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fagar%2Fagar.c;h=aa4628404864affe29578122fb69f729f1a059c8;hp=b2809abd3bb91fc0a206ed698b3f0fef564dc7e7;hb=0ea6a2126c713207cb139d3329b15f0c9d735fbe;hpb=c2966d1879c825cfaf0e7d6848a5da052ee4a038 diff --git a/ccan/agar/agar.c b/ccan/agar/agar.c index b2809abd..aa462840 100644 --- a/ccan/agar/agar.c +++ b/ccan/agar/agar.c @@ -79,6 +79,7 @@ static int convert_edge_info(const struct aga_graph *g, int rc; eir.to = NULL; + eir.icost = ei->icost; /* Inherit the default from aga */ rc = sr->gr->edge_info(sr->gr, nr, e, &eir); @@ -87,6 +88,8 @@ static int convert_edge_info(const struct aga_graph *g, else ei->to = NULL; + ei->icost = eir.icost; + return rc; } @@ -164,6 +167,7 @@ int agar_edge_info(const struct agar_graph *gr, const void *nr, const void *e, int rc; eir->to = NULL; + eir->icost = 1; rc = gr->edge_info(gr, nr, e, eir); assert(rc <= 0); return rc; @@ -230,3 +234,105 @@ bool agar_bfs_explore(struct agar_state *sr, const void *nr, *nextr = n_to_nr(sr, next); return true; } + +/* + * Dijkstra's algorithm + */ + +struct agar_state *agar_dijkstra_new(void *ctx, struct agar_graph *gr, + const void *nr) +{ + struct agar_state *sr = agar_new(ctx, gr); + + if (aga_dijkstra_start(&sr->g, nr_to_n(sr, nr)) < 0) { + tal_free(sr); + return NULL; + } + + return sr; +} + +bool agar_dijkstra_step(struct agar_state *sr, const void **nextr) +{ + struct aga_node *next = aga_dijkstra_step(&sr->g); + + if (!next) + return false; + + *nextr = n_to_nr(sr, next); + return true; +} + +bool agar_dijkstra_path(struct agar_state *sr, const void *destr, + aga_icost_t *total_cost, + const void **prevr, const void **prevedge) +{ + struct aga_node *dest = nr_to_n(sr, destr); + struct aga_node *prev; + + if (!aga_dijkstra_path(&sr->g, dest, total_cost, &prev, prevedge)) + return false; + + /* + * When destr is the same as the source node, there obviously + * isn't a previous node or edge. In that case aga, sets them + * to NULL. But for agar, NULL could be a valid node + * references (particularly if using ptrint). So we don't + * have much choice here but to leave *prevr as undefined when + * destr is the source node. */ + if (prevr && prev) + *prevr = n_to_nr(sr, prev); + + return true; +} + +void agar_dijkstra_complete(struct agar_state *sr) +{ + aga_dijkstra_complete(&sr->g); +} + + +/* + * Bellman-Ford algorithm + */ + +struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr, + const void *nr) +{ + struct agar_state *sr = agar_new(ctx, gr); + + if (aga_bellman_ford_start(&sr->g, nr_to_n(sr, nr)) < 0) { + tal_free(sr); + return NULL; + } + + return sr; +} + +bool agar_bellman_ford_path(struct agar_state *sr, const void *destr, + aga_icost_t *total_cost, + const void **prevr, const void **prevedge) +{ + struct aga_node *dest = nr_to_n(sr, destr); + struct aga_node *prev; + + if (!aga_bellman_ford_path(&sr->g, dest, total_cost, &prev, prevedge)) + return false; + + /* + * When destr is the same as the source node, there obviously + * isn't a previous node or edge. In that case aga sets them + * to NULL. But for agar, NULL could be a valid node + * references (particularly if using ptrint). So we don't + * have much choice here but to leave *prevr as undefined when + * destr is the source node. */ + if (prevr && prev) + *prevr = n_to_nr(sr, prev); + + return true; +} + +void agar_bellman_ford_complete(struct agar_state *sr) +{ + aga_bellman_ford_complete(&sr->g); +}