11#include "config.h"
22#include <ccan/bitmap/bitmap.h>
3- #include <ccan/lqueue/lqueue.h>
43#include <ccan/tal/tal.h>
54#include <plugins/askrene/algorithm.h>
65#include <plugins/askrene/priorityqueue.h>
@@ -10,44 +9,37 @@ static const s64 INFINITE = INT64_MAX;
109#define MAX (x , y ) (((x) > (y)) ? (x) : (y))
1110#define MIN (x , y ) (((x) < (y)) ? (x) : (y))
1211
13- /* Simple queue to traverse the network. */
14- struct queue_data {
15- u32 idx ;
16- struct lqueue_link ql ;
17- };
18-
1912bool BFS_path (const tal_t * ctx , const struct graph * graph ,
2013 const struct node source , const struct node destination ,
2114 const s64 * capacity , const s64 cap_threshold , struct arc * prev )
2215{
23- tal_t * this_ctx = tal (ctx , tal_t );
16+ const tal_t * this_ctx = tal (ctx , tal_t );
2417 bool target_found = false;
18+ assert (graph );
2519 const size_t max_num_arcs = graph_max_num_arcs (graph );
2620 const size_t max_num_nodes = graph_max_num_nodes (graph );
2721
2822 /* check preconditions */
29- if (!graph || source .idx >= max_num_nodes || !capacity || !prev )
30- goto finish ;
31-
32- if (tal_count (capacity ) != max_num_arcs ||
33- tal_count (prev ) != max_num_nodes )
34- goto finish ;
23+ assert (source .idx < max_num_nodes );
24+ assert (capacity );
25+ assert (prev );
26+ assert (tal_count (capacity ) == max_num_arcs );
27+ assert (tal_count (prev ) == max_num_nodes );
3528
3629 for (size_t i = 0 ; i < max_num_nodes ; i ++ )
3730 prev [i ].idx = INVALID_INDEX ;
3831
39- LQUEUE (struct queue_data , ql ) myqueue = LQUEUE_INIT ;
40- struct queue_data * qdata ;
32+ /* A minimalistic queue is implemented here. Nodes are not visited more
33+ * than once, therefore a maximum size of max_num_nodes is sufficient.
34+ * max_num_arcs would work as well but we expect max_num_arcs to be a
35+ * factor >10 greater than max_num_nodes. */
36+ u32 * queue = tal_arr (this_ctx , u32 , max_num_nodes );
37+ size_t queue_start = 0 , queue_end = 0 ;
4138
42- qdata = tal (this_ctx , struct queue_data );
43- qdata -> idx = source .idx ;
44- lqueue_enqueue (& myqueue , qdata );
39+ queue [queue_end ++ ] = source .idx ;
4540
46- while (!lqueue_empty (& myqueue )) {
47- qdata = lqueue_dequeue (& myqueue );
48- struct node cur = {.idx = qdata -> idx };
49-
50- tal_free (qdata );
41+ while (queue_start < queue_end ) {
42+ struct node cur = {.idx = queue [queue_start ++ ]};
5143
5244 if (cur .idx == destination .idx ) {
5345 target_found = true;
@@ -69,13 +61,11 @@ bool BFS_path(const tal_t *ctx, const struct graph *graph,
6961
7062 prev [next .idx ] = arc ;
7163
72- qdata = tal (this_ctx , struct queue_data );
73- qdata -> idx = next .idx ;
74- lqueue_enqueue (& myqueue , qdata );
64+ assert (queue_end < max_num_nodes );
65+ queue [queue_end ++ ] = next .idx ;
7566 }
7667 }
7768
78- finish :
7969 tal_free (this_ctx );
8070 return target_found ;
8171}
@@ -87,24 +77,25 @@ bool dijkstra_path(const tal_t *ctx, const struct graph *graph,
8777 s64 * distance )
8878{
8979 bool target_found = false;
80+ assert (graph );
9081 const size_t max_num_arcs = graph_max_num_arcs (graph );
9182 const size_t max_num_nodes = graph_max_num_nodes (graph );
92- tal_t * this_ctx = tal (ctx , tal_t );
83+ const tal_t * this_ctx = tal (ctx , tal_t );
9384
9485 /* check preconditions */
95- if (!graph || source .idx >=max_num_nodes || !cost || !capacity ||
96- !prev || !distance )
97- goto finish ;
86+ assert (source .idx < max_num_nodes );
87+ assert (cost );
88+ assert (capacity );
89+ assert (prev );
90+ assert (distance );
9891
9992 /* if prune is true then the destination cannot be invalid */
100- if (destination .idx >=max_num_nodes && prune )
101- goto finish ;
93+ assert (destination .idx < max_num_nodes || !prune );
10294
103- if (tal_count (cost ) != max_num_arcs ||
104- tal_count (capacity ) != max_num_arcs ||
105- tal_count (prev ) != max_num_nodes ||
106- tal_count (distance ) != max_num_nodes )
107- goto finish ;
95+ assert (tal_count (cost ) == max_num_arcs );
96+ assert (tal_count (capacity ) == max_num_arcs );
97+ assert (tal_count (prev ) == max_num_nodes );
98+ assert (tal_count (distance ) == max_num_nodes );
10899
109100 /* FIXME: maybe this is unnecessary */
110101 bitmap * visited = tal_arrz (this_ctx , bitmap ,
@@ -217,9 +208,8 @@ static s64 get_augmenting_flow(const struct graph *graph,
217208 * Sends an amount of flow through an arc, changing the flow balance of the
218209 * nodes connected by the arc and the [residual] capacity of the arc and its
219210 * dual. */
220- static inline void sendflow (const struct graph * graph , const struct arc arc ,
221- const s64 flow , s64 * arc_capacity ,
222- s64 * node_balance )
211+ static void sendflow (const struct graph * graph , const struct arc arc ,
212+ const s64 flow , s64 * arc_capacity , s64 * node_balance )
223213{
224214 const struct arc dual = arc_dual (graph , arc );
225215
@@ -279,20 +269,17 @@ bool simple_feasibleflow(const tal_t *ctx,
279269 s64 * capacity ,
280270 s64 amount )
281271{
282- tal_t * this_ctx = tal (ctx , tal_t );
272+ const tal_t * this_ctx = tal (ctx , tal_t );
273+ assert (graph );
283274 const size_t max_num_arcs = graph_max_num_arcs (graph );
284275 const size_t max_num_nodes = graph_max_num_nodes (graph );
285276
286277 /* check preconditions */
287- if (amount < 0 )
288- goto finish ;
289-
290- if (!graph || source .idx >= max_num_nodes ||
291- destination .idx >= max_num_nodes || !capacity )
292- goto finish ;
293-
294- if (tal_count (capacity ) != max_num_arcs )
295- goto finish ;
278+ assert (amount > 0 );
279+ assert (source .idx < max_num_nodes );
280+ assert (destination .idx < max_num_nodes );
281+ assert (capacity );
282+ assert (tal_count (capacity ) == max_num_arcs );
296283
297284 /* path information
298285 * prev: is the id of the arc that lead to the node. */
@@ -343,8 +330,8 @@ s64 node_balance(const struct graph *graph,
343330
344331/* Helper.
345332 * Compute the reduced cost of an arc. */
346- static inline s64 reduced_cost (const struct graph * graph , const struct arc arc ,
347- const s64 * cost , const s64 * potential )
333+ static s64 reduced_cost (const struct graph * graph , const struct arc arc ,
334+ const s64 * cost , const s64 * potential )
348335{
349336 struct node src = arc_tail (graph , arc );
350337 struct node dst = arc_head (graph , arc );
@@ -368,7 +355,7 @@ static struct node dijkstra_nearest_sink(const tal_t *ctx,
368355 s64 * distance )
369356{
370357 struct node target = {.idx = INVALID_INDEX };
371- tal_t * this_ctx = tal (ctx , tal_t );
358+ const tal_t * this_ctx = tal (ctx , tal_t );
372359
373360 if (!this_ctx )
374361 /* bad allocation */
@@ -521,7 +508,7 @@ bool mcf_refinement(const tal_t *ctx,
521508 s64 * potential )
522509{
523510 bool solved = false;
524- tal_t * this_ctx = tal (ctx , tal_t );
511+ const tal_t * this_ctx = tal (ctx , tal_t );
525512
526513 if (!this_ctx )
527514 /* bad allocation */
@@ -639,24 +626,23 @@ bool simple_mcf(const tal_t *ctx, const struct graph *graph,
639626 const struct node source , const struct node destination ,
640627 s64 * capacity , s64 amount , const s64 * cost )
641628{
642- tal_t * this_ctx = tal (ctx , tal_t );
629+ const tal_t * this_ctx = tal (ctx , tal_t );
643630 if (!this_ctx )
644631 /* bad allocation */
645632 goto fail ;
646633
647- if (!graph )
648- goto fail ;
649-
634+ assert (graph );
650635 const size_t max_num_arcs = graph_max_num_arcs (graph );
651636 const size_t max_num_nodes = graph_max_num_nodes (graph );
652637
653- if (amount < 0 || source .idx >= max_num_nodes ||
654- destination .idx >= max_num_nodes || !capacity || !cost )
655- goto fail ;
656-
657- if (tal_count (capacity ) != max_num_arcs ||
658- tal_count (cost ) != max_num_arcs )
659- goto fail ;
638+ /* check preconditions */
639+ assert (amount > 0 );
640+ assert (source .idx < max_num_nodes );
641+ assert (destination .idx < max_num_nodes );
642+ assert (capacity );
643+ assert (cost );
644+ assert (tal_count (capacity ) == max_num_arcs );
645+ assert (tal_count (cost ) == max_num_arcs );
660646
661647 s64 * potential = tal_arrz (this_ctx , s64 , max_num_nodes );
662648 s64 * excess = tal_arrz (this_ctx , s64 , max_num_nodes );
@@ -681,12 +667,15 @@ bool simple_mcf(const tal_t *ctx, const struct graph *graph,
681667
682668s64 flow_cost (const struct graph * graph , const s64 * capacity , const s64 * cost )
683669{
670+ assert (graph );
684671 const size_t max_num_arcs = graph_max_num_arcs (graph );
685672 s64 total_cost = 0 ;
686673
687- assert (graph && capacity && cost );
688- assert (tal_count (capacity ) == max_num_arcs &&
689- tal_count (cost ) == max_num_arcs );
674+ /* check preconditions */
675+ assert (capacity );
676+ assert (cost );
677+ assert (tal_count (capacity ) == max_num_arcs );
678+ assert (tal_count (cost ) == max_num_arcs );
690679
691680 for (u32 i = 0 ; i < max_num_arcs ; i ++ ) {
692681 struct arc arc = {.idx = i };
0 commit comments