fast_down_ffi/config.rs
1use fast_down::{ProgressEntry, Proxy};
2use parking_lot::Mutex;
3use std::{collections::HashMap, net::IpAddr, sync::Arc, time::Duration};
4
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[derive(Debug, Clone, PartialEq, Eq, Default)]
7pub enum WriteMethod {
8 #[default]
9 Mmap,
10 Std,
11}
12
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14#[derive(Debug, Clone)]
15pub struct Config {
16 /// Number of threads. Recommended: `32` / `16` / `8`. More threads does not always mean faster.
17 pub threads: usize,
18 /// Proxy setting. Supports https, http, and socks5 proxies.
19 pub proxy: Proxy<String>,
20 /// Custom request headers.
21 pub headers: HashMap<String, String>,
22 /// Minimum chunk size in bytes. Recommended: `8 * 1024 * 1024`
23 ///
24 /// - Chunks that are too small may cause heavy contention.
25 /// - When chunking is no longer possible, speculative mode is used.
26 pub min_chunk_size: u64,
27 /// Whether to ensure data is fully flushed to disk. Recommended: `false`
28 ///
29 /// Set to `true` only if you need to power off immediately after download.
30 pub sync_all: bool,
31 /// Write buffer size in bytes. Recommended: `16 * 1024 * 1024`
32 ///
33 /// - Only effective for [`WriteMethod::Std`]. Helps convert random writes into sequential writes.
34 /// - Not used for [`WriteMethod::Mmap`], as the buffer is managed by the OS.
35 pub write_buffer_size: usize,
36 /// Cache high watermark in bytes. Recommended: `16 * 1024 * 1024`
37 ///
38 /// When the byte merge buffer reaches this size, a merge flush is triggered
39 /// to reduce the buffer to `cache_low_watermark` or below.
40 ///
41 /// - Only effective for [`WriteMethod::Std`].
42 /// - Not used for [`WriteMethod::Mmap`].
43 pub cache_high_watermark: usize,
44 /// Cache low watermark in bytes. Recommended: `8 * 1024 * 1024`
45 ///
46 /// After a merge flush, the byte merge buffer size is reduced to this level or below.
47 ///
48 /// - Only effective for [`WriteMethod::Std`].
49 /// - Not used for [`WriteMethod::Mmap`].
50 pub cache_low_watermark: usize,
51 /// Write queue capacity. Recommended: `10240`
52 ///
53 /// If download threads fill the write queue, backpressure is applied to
54 /// slow down downloads and prevent excessive memory usage.
55 pub write_queue_cap: usize,
56 /// Default retry interval after a request failure. Recommended: `500ms`
57 ///
58 /// If the server returns a `Retry-After` header, that value takes precedence.
59 pub retry_gap: Duration,
60 /// Pull timeout. Recommended: `5000ms`
61 ///
62 /// If no bytes are received within `pull_timeout` after sending the request,
63 /// the connection is dropped and re-established. This helps TCP detect
64 /// congestion and can improve download speed.
65 pub pull_timeout: Duration,
66 /// Whether to accept invalid certificates (dangerous). Recommended: `false`
67 pub accept_invalid_certs: bool,
68 /// Whether to accept invalid hostnames (dangerous). Recommended: `false`
69 pub accept_invalid_hostnames: bool,
70 /// Write method. Recommended: [`WriteMethod::Mmap`]
71 ///
72 /// - [`WriteMethod::Mmap`] is fastest — it delegates writes to the OS, but:
73 /// 1. On 32-bit systems, the maximum file size is 4 GB, so it automatically
74 /// falls back to [`WriteMethod::Std`].
75 /// 2. The file size must be known, otherwise it falls back to [`WriteMethod::Std`].
76 /// 3. In rare cases, the OS may cache all data in memory and flush it all
77 /// at once after the download completes, causing a long post-download delay.
78 /// - [`WriteMethod::Std`] has the best compatibility. It sorts chunks within
79 /// `write_buffer_size` to approximate sequential writes.
80 #[cfg(feature = "file")]
81 pub write_method: WriteMethod,
82 /// Number of retries for fetching metadata. Recommended: `10`. Note: this is not
83 /// the retry count during download.
84 pub retry_times: usize,
85 /// Local IP addresses to bind for outgoing requests. Recommended: `Vec::new()`
86 ///
87 /// If you have multiple network interfaces, you can provide their IP addresses;
88 /// requests will be rotated among them. This may not always improve speed.
89 pub local_address: Vec<IpAddr>,
90 /// Maximum number of speculative workers. Recommended: `3`
91 ///
92 /// When the remaining chunk is smaller than `min_chunk_size` and cannot be split,
93 /// speculative mode is used. Up to `max_speculative` workers compete on the same
94 /// chunk to prevent the download from stalling near 99%.
95 pub max_speculative: usize,
96 /// Already downloaded chunks. Pass `Vec::new()` to download the entire file.
97 pub downloaded_chunk: Arc<Mutex<Vec<ProgressEntry>>>,
98 /// Smoothing window for downloaded chunks in bytes. Recommended: `8 * 1024`
99 ///
100 /// Filters out small gaps in `downloaded_chunk` that are smaller than
101 /// `chunk_window` to reduce the number of HTTP requests.
102 pub chunk_window: u64,
103}
104
105impl Default for Config {
106 fn default() -> Self {
107 Self {
108 retry_times: 10,
109 threads: 32,
110 proxy: Proxy::System,
111 headers: HashMap::new(),
112 sync_all: false,
113 min_chunk_size: 8 * 1024 * 1024,
114 write_buffer_size: 16 * 1024 * 1024,
115 cache_high_watermark: 16 * 1024 * 1024,
116 cache_low_watermark: 8 * 1024 * 1024,
117 write_queue_cap: 10240,
118 retry_gap: Duration::from_millis(500),
119 pull_timeout: Duration::from_secs(5),
120 accept_invalid_certs: false,
121 accept_invalid_hostnames: false,
122 local_address: Vec::new(),
123 max_speculative: 3,
124 #[cfg(feature = "file")]
125 write_method: WriteMethod::Mmap,
126 downloaded_chunk: Arc::default(),
127 chunk_window: 8 * 1024,
128 }
129 }
130}