pub fn allocate(
sources: &[SourcePlan],
requested: usize,
per_host: usize,
total: usize,
) -> Vec<usize>Expand description
Split requested connections across sources, honouring every ceiling.
Returns one entry per source, in input order — a caller’s own per-source bookkeeping (targets, hostnames, progress rows) is index-aligned with this, and re-ordering the result to put the best mirror first would silently scramble it.
The three ceilings, all enforced:
requested— what the caller asked for, usually-xor a measured concurrency.total— the aggregate socket ceiling. Eight connections across two mirrors is still eight sockets, which is the number a server operator actually feels.per_host, narrowed by anySourcePlan::max_connections.
§The allocation rule
Every source that gets anything gets at least one, best-ranked first; the
remainder is distributed by the divisor method — repeatedly give the next
connection to whichever source maximises weight / (held + 1). That is the
standard proportional-apportionment rule, and it is used here for the
property that makes it standard: it never leaves a source with a share that
another source’s ranking cannot justify, and it terminates in exactly
budget steps with no rounding residue to strand.
Ties break on (priority, index) so two runs against the same mirror list
allocate identically. A download that opens different mirrors on every
attempt cannot be debugged from its logs.