use asupersync::raptorq::decoder::{InactivationDecoder, ReceivedSymbol};
use asupersync::raptorq::gf256::{Gf256, gf256_addmul_slice, gf256_mul_slice};
use asupersync::raptorq::systematic::SystematicEncoder;
fn main() {
println!("Starting RaptorQ large K profiling test...");
let k = 1024;
let symbol_size = 1316; let loss_fraction = 0.6; let loss_count = (k as f64 * loss_fraction) as usize;
let repair_margin = 50;
let extra_repair = loss_count + repair_margin;
let seed = 42u64;
println!(
"Testing K={}, symbol_size={}, loss_fraction={:.1}%",
k,
symbol_size,
loss_fraction * 100.0
);
let mut source_symbols = Vec::with_capacity(k);
let mut rng_state = 0x12345678u64;
for i in 0..k {
let mut symbol = vec![0u8; symbol_size];
for byte in symbol.iter_mut() {
rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345);
*byte = ((rng_state >> 16) + i as u64) as u8;
}
source_symbols.push(symbol);
}
println!("Testing GF256 bulk operations...");
for iteration in 0..100 {
let mut test_data = vec![42u8; 65536]; let scalar = Gf256::new((iteration % 255 + 1) as u8);
gf256_mul_slice(&mut test_data, scalar);
let src_data = vec![(iteration % 256) as u8; 65536];
gf256_addmul_slice(&mut test_data, &src_data, scalar);
}
println!("Creating encoder...");
let encoder = SystematicEncoder::new(&source_symbols, symbol_size, seed)
.expect("encoder creation failed");
println!("Generating repair symbols...");
let mut repair_symbols = Vec::with_capacity(extra_repair);
for i in 0..extra_repair {
let esi = k as u32 + i as u32;
let symbol = encoder.repair_symbol(esi);
repair_symbols.push((esi, symbol));
}
println!("Creating loss pattern and received symbols...");
let mut loss_pattern = vec![false; k]; rng_state = 0xDEADBEEF;
let mut losses_applied = 0;
while losses_applied < loss_count {
rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345);
let idx = (rng_state % k as u64) as usize;
if !loss_pattern[idx] {
loss_pattern[idx] = true; losses_applied += 1;
}
}
println!("Loss pattern: {}/{} symbols lost", losses_applied, k);
println!("Creating decoder...");
let decoder = InactivationDecoder::new(k, symbol_size, seed);
let mut received_symbols = decoder.constraint_symbols();
for (i, &is_lost) in loss_pattern.iter().enumerate() {
if !is_lost {
received_symbols.push(ReceivedSymbol::source(i as u32, source_symbols[i].clone()));
}
}
for (repair_esi, repair_data) in repair_symbols {
let (cols, coefs) = decoder
.repair_equation(repair_esi)
.expect("repair equation failed");
received_symbols.push(ReceivedSymbol::repair(repair_esi, cols, coefs, repair_data));
}
println!("Received symbols: {}", received_symbols.len());
println!("Starting decode - this is where matrix solve happens...");
let start = std::time::Instant::now();
let decode_result = decoder.decode(&received_symbols).expect("decode failed");
let decode_time = start.elapsed();
println!(
"Decode completed in {:.2}ms",
decode_time.as_secs_f64() * 1000.0
);
let decoded_symbols = decode_result.source;
assert_eq!(
decoded_symbols.len(),
k,
"Decoded symbol count mismatch: {} vs {}",
decoded_symbols.len(),
k
);
for (i, (original, decoded)) in source_symbols
.iter()
.zip(decoded_symbols.iter())
.enumerate()
{
assert_eq!(original, decoded, "Symbol {i} data mismatch!");
}
println!("Success! Decoded data matches original.");
println!("Profile complete. Check perf report for hotspots.");
}