Use integral scores to select stream suppliers

This commit is contained in:
evgeny committed 2026-10-13 01:14:38 +02:00
1 parent 83c652a810
commit 2cc9834e4c
5 files changed
+105 -39

No files matched your search

+37
View File
@@ -7,6 +7,7 @@
#include "../src/stream/stream_metrics.h"
#include "../src/stream/stream_load.h"
#include "../src/stream/stream_optimizer.h"
#include "../src/stream/stream_network.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#include "test_clock.h"
@@ -382,6 +383,41 @@ static void test_source_timer(void) {
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "[PASS] source: 100ms timer, immediate full batch, padding, finish and cancellation on destroy");
}
/* Близкий сосед, цена дополнительных hops и проблем сравниваются в одних единицах, неизвестный RTT не становится нулём. */
static void test_supplier_score(void) {
struct stream_receive_info near = {.rtt_ms = 10, .path_rtt_ms = 80, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 3}};
struct stream_receive_info far = {.rtt_ms = 45, .path_rtt_ms = 40, .rtt_valid = 1, .path_rtt_valid = 1, .path = {.count = 2}};
struct stream_metric_snapshot clean = {.blocks = 100}, late = {.blocks = 100, .late_blocks = 2};
CHECK(stream_supplier_score(&near, &clean, 1) == 109 && stream_supplier_score(&far, &clean, 1) == 136);
/* Обычная сумма RTT предпочла бы far (85 < 90); удвоенный RTT соседа предпочитает near. */
CHECK(stream_supplier_score(&near, &clean, 1) < stream_supplier_score(&far, &clean, 1));
CHECK(stream_supplier_score(&near, &late, 1) == 129);
CHECK(stream_supplier_score(&near, &late, 1) < stream_supplier_score(&far, &clean, 1));
late.late_blocks = 3;
CHECK(stream_supplier_score(&near, &late, 1) > stream_supplier_score(&far, &clean, 1));
far = near; far.rtt_ms = 9; far.path.count = 4;
CHECK(stream_supplier_score(&far, &clean, 1) == 110);
CHECK(stream_supplier_score(&near, &clean, 1) < stream_supplier_score(&far, &clean, 1));
late = (struct stream_metric_snapshot){.blocks = 4, .late_blocks = 1, .stops = 7};
CHECK(stream_supplier_score(&near, &late, 1) == 369);
late.lag_ms = STREAM_LATE_MS;
CHECK(stream_supplier_score(&near, &late, 1) == 369);
late.lag_ms++;
CHECK(stream_supplier_score(&near, &late, 1) == 1109);
late.lag_ms = 0; late.stopped = 1;
CHECK(stream_supplier_score(&near, &late, 1) == 1109);
late.stopped = 0; late.late_blocks = late.blocks;
CHECK(stream_supplier_score(&near, &late, 1) == 1109); /* История остановок не превышает лимит штрафа. */
CHECK(stream_supplier_score(&near, &late, 0) == 109);
near.rtt_valid = 0;
CHECK(stream_supplier_score(&near, &clean, 1) == UINT64_MAX);
near.rtt_valid = 1; near.path_rtt_valid = 0;
CHECK(stream_supplier_score(&near, &clean, 1) == UINT64_MAX);
near.path_rtt_valid = 1; near.rtt_ms = near.path_rtt_ms = UINT32_MAX;
CHECK(stream_supplier_score(&near, &late, 1) == 3 * (uint64_t)UINT32_MAX + 1009);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "[PASS] supplier score: nearby peer, hop cost, problem tradeoffs, 1000ms cap, unknown and wide RTT");
}
static void test_probe_schedule(void) {
struct stream_probe_schedule schedule = {0};
CHECK(stream_probe_schedule_tick(&schedule, 0, 40, 0) == 32 && schedule.cycle == 1);
@@ -414,6 +450,7 @@ int main(void) {
test_wire(); CHECK(u_get_allocated_count() == allocations);
test_load(); CHECK(u_get_allocated_count() == allocations);
test_probe_schedule(); CHECK(u_get_allocated_count() == allocations);
test_supplier_score(); CHECK(u_get_allocated_count() == allocations);
test_fec_and_padding(); CHECK(u_get_allocated_count() == allocations);
test_ring_and_conflicts(); CHECK(u_get_allocated_count() == allocations);
test_relative_metrics(); CHECK(u_get_allocated_count() == allocations);