stormdl_segment/
splitter.rs1use std::time::Duration;
2
3#[derive(Debug, Clone, Copy)]
4pub enum SplitStrategy {
5 Static(usize),
6 Adaptive,
7}
8
9pub fn optimal_segments(file_size: u64, measured_bw: f64, rtt: Duration) -> usize {
10 let bdp = measured_bw * rtt.as_secs_f64();
11 let tcp_window = 65536.0;
12 let min_connections = (bdp / tcp_window).ceil() as usize;
13
14 let max_connections = match file_size {
15 0..=1_000_000 => 1,
16 1_000_001..=10_000_000 => 4,
17 10_000_001..=100_000_000 => 8,
18 100_000_001..=1_000_000_000 => 16,
19 _ => 32,
20 };
21
22 min_connections.clamp(1, max_connections)
23}
24
25pub fn initial_segments(file_size: u64) -> usize {
26 match file_size {
27 0..=1_000_000 => 1,
28 1_000_001..=10_000_000 => 4,
29 _ => 8,
30 }
31}
32
33pub fn turbo_segments(file_size: u64) -> usize {
34 match file_size {
35 0..=1_000_000 => 1,
36 1_000_001..=10_000_000 => 8,
37 _ => 16,
38 }
39}
40
41pub fn split_range(total_size: u64, num_segments: usize) -> Vec<stormdl_core::ByteRange> {
42 if num_segments == 0 || total_size == 0 {
43 return vec![];
44 }
45
46 let segment_size = total_size / num_segments as u64;
47 let remainder = total_size % num_segments as u64;
48
49 let mut ranges = Vec::with_capacity(num_segments);
50 let mut offset = 0;
51
52 for i in 0..num_segments {
53 let extra = if i < remainder as usize { 1 } else { 0 };
54 let size = segment_size + extra;
55 ranges.push(stormdl_core::ByteRange::new(offset, offset + size));
56 offset += size;
57 }
58
59 ranges
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_split_range_even() {
68 let ranges = split_range(100, 4);
69 assert_eq!(ranges.len(), 4);
70 assert_eq!(ranges[0], stormdl_core::ByteRange::new(0, 25));
71 assert_eq!(ranges[1], stormdl_core::ByteRange::new(25, 50));
72 assert_eq!(ranges[2], stormdl_core::ByteRange::new(50, 75));
73 assert_eq!(ranges[3], stormdl_core::ByteRange::new(75, 100));
74 }
75
76 #[test]
77 fn test_split_range_uneven() {
78 let ranges = split_range(10, 3);
79 assert_eq!(ranges.len(), 3);
80 assert_eq!(ranges[0].len() + ranges[1].len() + ranges[2].len(), 10);
81 }
82}