X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fagar%2Fagar.c;h=0baab325b58e678ba108e3fa2a09257ca92b6d86;hb=9d2d2c49f053018724bcc6e37029da10b7c3d60d;hp=b2809abd3bb91fc0a206ed698b3f0fef564dc7e7;hpb=c2966d1879c825cfaf0e7d6848a5da052ee4a038;p=ccan diff --git a/ccan/agar/agar.c b/ccan/agar/agar.c index b2809abd..0baab325 100644 --- a/ccan/agar/agar.c +++ b/ccan/agar/agar.c @@ -59,7 +59,7 @@ static struct aga_node *nr_to_n(struct agar_state *sr, const void *nr) assert(rc); } - return nn ? &nn->n : NULL; + return &nn->n; } static const void *n_to_nr(struct agar_state *sr, const struct aga_node *n) @@ -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); +}