Skip to content

Commit 7c7a4f8

Browse files
committed
askrene: Remove index indirection from squash_flows, simplify sorting.
We don't need to convert to strings, we can compare directly. This removes the final use of the index arrays. This of course changes the order of returned routes, which alters test_real_biases, since that biases against the final channel in the *first* route. Took me far too long to diagnose that! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 2735673 commit 7c7a4f8

File tree

2 files changed

+29
-64
lines changed

2 files changed

+29
-64
lines changed

plugins/askrene/refine.c

Lines changed: 27 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -433,24 +433,6 @@ static struct amount_msat increase_flows(const struct route_query *rq,
433433
return all_deliver;
434434
}
435435

436-
static void write_selected_flows(const tal_t *ctx, size_t *flows_index,
437-
struct flow ***flows)
438-
{
439-
struct flow **tmp_flows = tal_arr(ctx, struct flow *, 0);
440-
for (size_t i = 0; i < tal_count(flows_index); i++) {
441-
tal_arr_expand(&tmp_flows, (*flows)[flows_index[i]]);
442-
(*flows)[flows_index[i]] = NULL;
443-
}
444-
for (size_t i = 0; i < tal_count(*flows); i++) {
445-
(*flows)[i] = tal_free((*flows)[i]);
446-
}
447-
tal_resize(flows, 0);
448-
for (size_t i = 0; i < tal_count(tmp_flows); i++) {
449-
tal_arr_expand(flows, tmp_flows[i]);
450-
}
451-
tal_free(tmp_flows);
452-
}
453-
454436
const char *refine_flows(const tal_t *ctx, struct route_query *rq,
455437
struct amount_msat deliver, struct flow ***flows,
456438
u32 *bottleneck_idx)
@@ -517,64 +499,47 @@ const char *refine_flows(const tal_t *ctx, struct route_query *rq,
517499
return error_message;
518500
}
519501

520-
/* Order of flows according to path string */
521-
static int cmppath_flows(const size_t *a, const size_t *b, char **paths_str)
502+
/* Order of flows in lexicographic order */
503+
static int cmppath_flows(struct flow *const *a, struct flow *const *b, void *unused)
522504
{
523-
return strcmp(paths_str[*a], paths_str[*b]);
505+
const struct flow *fa = *a, *fb = *b;
506+
for (size_t i = 0; i < tal_count(fa->path); i++) {
507+
/* Shorter comes first */
508+
if (i >= tal_count(fb->path))
509+
return 1;
510+
if (fa->path[i] < fb->path[i])
511+
return -1;
512+
if (fa->path[i] > fb->path[i])
513+
return 1;
514+
}
515+
/* fa equal to fb, but is fb longer? */
516+
if (tal_count(fb->path) > tal_count(fa->path))
517+
return -1;
518+
/* equal */
519+
return 0;
524520
}
525521

526522
void squash_flows(const tal_t *ctx, struct route_query *rq,
527523
struct flow ***flows)
528524
{
529-
const tal_t *working_ctx = tal(ctx, tal_t);
530-
size_t *flows_index = tal_arrz(working_ctx, size_t, tal_count(*flows));
531-
char **paths_str = tal_arrz(working_ctx, char *, tal_count(*flows));
532-
struct amount_msat *max_deliverable = tal_arrz(
533-
working_ctx, struct amount_msat, tal_count(*flows));
534-
535-
for (size_t i = 0; i < tal_count(flows_index); i++) {
536-
const struct flow *flow = (*flows)[i];
537-
struct short_channel_id_dir scidd;
538-
flows_index[i] = i;
539-
paths_str[i] = tal_strdup(working_ctx, "");
540-
max_deliverable[i] = flow_max_deliverable(rq, flow, NULL);
541-
542-
for (size_t j = 0; j < tal_count(flow->path); j++) {
543-
scidd.scid =
544-
gossmap_chan_scid(rq->gossmap, flow->path[j]);
545-
scidd.dir = flow->dirs[j];
546-
tal_append_fmt(
547-
&paths_str[i], "%s%s", j > 0 ? "->" : "",
548-
fmt_short_channel_id_dir(working_ctx, &scidd));
549-
}
550-
}
551-
552-
asort(flows_index, tal_count(flows_index), cmppath_flows, paths_str);
553-
for (size_t i = 0; i < tal_count(flows_index); i++) {
554-
const size_t j = i + 1;
555-
struct amount_msat combined;
556-
struct amount_msat max = max_deliverable[flows_index[i]];
525+
asort(*flows, tal_count(*flows), cmppath_flows, NULL);
526+
for (size_t i = 0; i < tal_count(*flows); i++) {
527+
struct flow *flow = (*flows)[i];
557528

558529
/* same path? We merge */
559-
while (j < tal_count(flows_index) &&
560-
cmppath_flows(&flows_index[i],
561-
&flows_index[j],
562-
paths_str) == 0) {
563-
if (!amount_msat_add(
564-
&combined, (*flows)[flows_index[i]]->delivers,
565-
(*flows)[flows_index[j]]->delivers))
530+
while (i + 1 < tal_count(*flows) &&
531+
cmppath_flows(&flow, &(*flows)[i+1], NULL) == 0) {
532+
struct amount_msat combined, max = flow_max_deliverable(rq, flow, NULL);
533+
534+
if (!amount_msat_add(&combined, flow->delivers, (*flows)[i+1]->delivers))
566535
abort();
567536
/* do we break any HTLC max limits */
568537
if (amount_msat_greater(combined, max))
569538
break;
570-
(*flows)[flows_index[i]]->delivers = combined;
571-
tal_arr_remove(&flows_index, j);
539+
flow->delivers = combined;
540+
tal_arr_remove(flows, i+1);
572541
}
573542
}
574-
575-
write_selected_flows(working_ctx, flows_index, flows);
576-
577-
tal_free(working_ctx);
578543
}
579544

580545
double flows_probability(const tal_t *ctx, struct route_query *rq,

tests/test_askrene.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,10 +1563,10 @@ def test_real_biases(node_factory, bitcoind):
15631563
# CI, it's slow.
15641564
if SLOW_MACHINE:
15651565
limit = 25
1566-
expected = ({1: 6, 2: 6, 4: 7, 8: 10, 16: 15, 32: 20, 64: 25, 100: 25}, 0)
1566+
expected = ({1: 6, 2: 6, 4: 7, 8: 12, 16: 14, 32: 19, 64: 25, 100: 25}, 0)
15671567
else:
15681568
limit = 100
1569-
expected = ({1: 19, 2: 27, 4: 36, 8: 48, 16: 71, 32: 83, 64: 95, 100: 96}, 0)
1569+
expected = ({1: 22, 2: 25, 4: 36, 8: 53, 16: 69, 32: 80, 64: 96, 100: 96}, 0)
15701570

15711571
l1.rpc.askrene_create_layer('biases')
15721572
num_changed = {}

0 commit comments

Comments
 (0)