Skip to content

Commit 565a92e

Browse files
committed
askrene: use flows array directly in remove_excess.
We don't need the indexes array, we can use this directly. We still set up the indexes array (for now) after we call this. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 31d28ba commit 565a92e

File tree

1 file changed

+43
-25
lines changed

1 file changed

+43
-25
lines changed

plugins/askrene/refine.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,15 @@ static int revcmp_flows(const size_t *a, const size_t *b, struct flow **flows)
177177
return 1;
178178
}
179179

180+
static int revcmp_flows_noidx(struct flow *const *a, struct flow *const *b, void *unused)
181+
{
182+
if (amount_msat_eq((*a)->delivers, (*b)->delivers))
183+
return 0;
184+
if (amount_msat_greater((*a)->delivers, (*b)->delivers))
185+
return -1;
186+
return 1;
187+
}
188+
180189
// TODO: unit test:
181190
// -> make a path
182191
// -> compute x = flow_max_deliverable
@@ -320,46 +329,56 @@ static struct amount_msat sum_all_deliver(struct flow **flows,
320329
return all_deliver;
321330
}
322331

332+
static struct amount_msat sum_all_deliver_noidx(struct flow **flows)
333+
{
334+
struct amount_msat all_deliver = AMOUNT_MSAT(0);
335+
for (size_t i = 0; i < tal_count(flows); i++) {
336+
if (!amount_msat_accumulate(&all_deliver,
337+
flows[i]->delivers))
338+
abort();
339+
}
340+
return all_deliver;
341+
}
342+
323343
/* It reduces the amount of the flows and/or removes some flows in order to
324344
* deliver no more than max_deliver. It will leave at least one flow.
325345
* Returns the total delivery amount. */
326-
static struct amount_msat remove_excess(struct flow **flows,
327-
size_t **flows_index,
346+
static struct amount_msat remove_excess(struct flow ***flows,
328347
struct amount_msat max_deliver)
329348
{
330-
if (tal_count(flows) == 0)
349+
if (tal_count(*flows) == 0)
331350
return AMOUNT_MSAT(0);
332351

333352
struct amount_msat all_deliver, excess;
334-
all_deliver = sum_all_deliver(flows, *flows_index);
353+
all_deliver = sum_all_deliver_noidx(*flows);
335354

336355
/* early exit: there is no excess */
337356
if (!amount_msat_sub(&excess, all_deliver, max_deliver) ||
338357
amount_msat_is_zero(excess))
339358
return all_deliver;
340359

341-
asort(*flows_index, tal_count(*flows_index), revcmp_flows, flows);
360+
asort(*flows, tal_count(*flows), revcmp_flows_noidx, NULL);
342361

343362
/* Remove the smaller parts if they deliver less than the
344363
* excess. */
345-
for (int i = tal_count(*flows_index) - 1; i >= 0; i--) {
364+
for (int i = tal_count(*flows) - 1; i >= 0; i--) {
346365
if (!amount_msat_deduct(&excess,
347-
flows[(*flows_index)[i]]->delivers))
366+
(*flows)[i]->delivers))
348367
break;
349368
if (!amount_msat_deduct(&all_deliver,
350-
flows[(*flows_index)[i]]->delivers))
369+
(*flows)[i]->delivers))
351370
abort();
352-
tal_arr_remove(flows_index, i);
371+
tal_arr_remove(flows, i);
353372
}
354373

355374
/* If we still have some excess, remove it from the
356375
* current flows in the same proportion every flow contributes to the
357376
* total. */
358377
struct amount_msat old_excess = excess;
359378
struct amount_msat old_deliver = all_deliver;
360-
for (size_t i = 0; i < tal_count(*flows_index); i++) {
379+
for (size_t i = 0; i < tal_count(*flows); i++) {
361380
double fraction = amount_msat_ratio(
362-
flows[(*flows_index)[i]]->delivers, old_deliver);
381+
(*flows)[i]->delivers, old_deliver);
363382
struct amount_msat remove;
364383

365384
if (!amount_msat_scale(&remove, old_excess, fraction))
@@ -372,15 +391,14 @@ static struct amount_msat remove_excess(struct flow **flows,
372391
abort();
373392

374393
if (!amount_msat_deduct(&all_deliver, remove) ||
375-
!amount_msat_deduct(&flows[(*flows_index)[i]]->delivers,
376-
remove))
394+
!amount_msat_deduct(&(*flows)[i]->delivers, remove))
377395
abort();
378396
}
379397

380398
/* any rounding error left, take it from the first */
381-
assert(tal_count(*flows_index) > 0);
399+
assert(tal_count(*flows) > 0);
382400
if (!amount_msat_deduct(&all_deliver, excess) ||
383-
!amount_msat_deduct(&flows[(*flows_index)[0]]->delivers, excess))
401+
!amount_msat_deduct(&(*flows)[0]->delivers, excess))
384402
abort();
385403
return all_deliver;
386404
}
@@ -464,6 +482,16 @@ const char *refine_flows(const tal_t *ctx, struct route_query *rq,
464482
struct amount_msat *min_deliverable;
465483
size_t *flows_index;
466484

485+
/* do not deliver more than HTLC_MAX allow us */
486+
for (size_t i = 0; i < tal_count(*flows); i++) {
487+
(*flows)[i]->delivers =
488+
amount_msat_min((*flows)[i]->delivers,
489+
flow_max_deliverable(rq, (*flows)[i], bottleneck_idx));
490+
}
491+
492+
/* remove excess from MCF granularity if any */
493+
remove_excess(flows, deliver);
494+
467495
min_deliverable = tal_arrz(working_ctx, struct amount_msat,
468496
tal_count(*flows));
469497
flows_index = tal_arrz(working_ctx, size_t, tal_count(*flows));
@@ -477,16 +505,6 @@ const char *refine_flows(const tal_t *ctx, struct route_query *rq,
477505
flows_index[i] = i;
478506
}
479507

480-
/* do not deliver more than HTLC_MAX allow us */
481-
for (size_t i = 0; i < tal_count(flows_index); i++) {
482-
(*flows)[flows_index[i]]->delivers =
483-
amount_msat_min((*flows)[flows_index[i]]->delivers,
484-
flow_max_deliverable(rq, (*flows)[flows_index[i]], bottleneck_idx));
485-
}
486-
487-
/* remove excess from MCF granularity if any */
488-
remove_excess(*flows, &flows_index, deliver);
489-
490508
/* increase flows if necessary to meet the target */
491509
increase_flows(rq, *flows, &flows_index, deliver, /* tolerance = */ 0.02);
492510

0 commit comments

Comments
 (0)