1use crate::compression::CompressionConfig;
7
8#[derive(Debug, Clone, Default)]
10pub struct PjsConfig {
11 pub compression: CompressionConfig,
13 pub parser: ParserConfig,
15 pub streaming: StreamingConfig,
17 pub simd: SimdConfig,
19}
20
21#[derive(Debug, Clone)]
23pub struct ParserConfig {
24 pub max_input_size_mb: usize,
26 pub buffer_initial_capacity: usize,
28 pub simd_min_size: usize,
30 pub enable_semantics: bool,
32}
33
34#[derive(Debug, Clone)]
36pub struct StreamingConfig {
37 pub max_frame_size: usize,
39 pub default_chunk_size: usize,
41 pub operation_timeout_ms: u64,
43 pub max_bandwidth_bps: u64,
45}
46
47#[derive(Debug, Clone)]
49pub struct SimdConfig {
50 pub batch_size: usize,
52 pub initial_capacity: usize,
54 pub avx512_alignment: usize,
56 pub vectorized_chunk_size: usize,
58 pub enable_stats: bool,
60}
61
62
63impl Default for ParserConfig {
64 fn default() -> Self {
65 Self {
66 max_input_size_mb: 100,
67 buffer_initial_capacity: 8192, simd_min_size: 4096, enable_semantics: true,
70 }
71 }
72}
73
74impl Default for StreamingConfig {
75 fn default() -> Self {
76 Self {
77 max_frame_size: 64 * 1024, default_chunk_size: 1024,
79 operation_timeout_ms: 5000, max_bandwidth_bps: 1_000_000, }
82 }
83}
84
85impl Default for SimdConfig {
86 fn default() -> Self {
87 Self {
88 batch_size: 100,
89 initial_capacity: 8192, avx512_alignment: 64,
91 vectorized_chunk_size: 32,
92 enable_stats: false,
93 }
94 }
95}
96
97impl PjsConfig {
99 pub fn low_latency() -> Self {
101 Self {
102 compression: CompressionConfig::default(),
103 parser: ParserConfig {
104 max_input_size_mb: 10,
105 buffer_initial_capacity: 4096, simd_min_size: 2048, enable_semantics: false, },
109 streaming: StreamingConfig {
110 max_frame_size: 16 * 1024, default_chunk_size: 512,
112 operation_timeout_ms: 1000, max_bandwidth_bps: 10_000_000, },
115 simd: SimdConfig {
116 batch_size: 50,
117 initial_capacity: 4096, avx512_alignment: 64,
119 vectorized_chunk_size: 16,
120 enable_stats: false,
121 },
122 }
123 }
124
125 pub fn high_throughput() -> Self {
127 Self {
128 compression: CompressionConfig::default(),
129 parser: ParserConfig {
130 max_input_size_mb: 1000, buffer_initial_capacity: 32768, simd_min_size: 8192, enable_semantics: true,
134 },
135 streaming: StreamingConfig {
136 max_frame_size: 256 * 1024, default_chunk_size: 4096,
138 operation_timeout_ms: 30000, max_bandwidth_bps: 100_000_000, },
141 simd: SimdConfig {
142 batch_size: 500,
143 initial_capacity: 32768, avx512_alignment: 64,
145 vectorized_chunk_size: 64,
146 enable_stats: true,
147 },
148 }
149 }
150
151 pub fn mobile() -> Self {
153 Self {
154 compression: CompressionConfig {
155 min_array_length: 1,
156 min_string_length: 2,
157 min_frequency_count: 1,
158 uuid_compression_potential: 0.5,
159 string_dict_threshold: 25.0, delta_threshold: 15.0, min_delta_potential: 0.2,
162 run_length_threshold: 10.0, min_compression_potential: 0.3,
164 min_numeric_sequence_size: 2,
165 },
166 parser: ParserConfig {
167 max_input_size_mb: 10,
168 buffer_initial_capacity: 2048, simd_min_size: 1024, enable_semantics: false,
171 },
172 streaming: StreamingConfig {
173 max_frame_size: 8 * 1024, default_chunk_size: 256,
175 operation_timeout_ms: 10000, max_bandwidth_bps: 100_000, },
178 simd: SimdConfig {
179 batch_size: 25,
180 initial_capacity: 2048, avx512_alignment: 32, vectorized_chunk_size: 8,
183 enable_stats: false,
184 },
185 }
186 }
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 #[test]
194 fn test_default_config() {
195 let config = PjsConfig::default();
196 assert_eq!(config.parser.max_input_size_mb, 100);
197 assert_eq!(config.streaming.max_frame_size, 64 * 1024);
198 assert_eq!(config.simd.batch_size, 100);
199 }
200
201 #[test]
202 fn test_low_latency_profile() {
203 let config = PjsConfig::low_latency();
204 assert_eq!(config.streaming.max_frame_size, 16 * 1024);
205 assert!(!config.parser.enable_semantics);
206 assert_eq!(config.streaming.operation_timeout_ms, 1000);
207 }
208
209 #[test]
210 fn test_high_throughput_profile() {
211 let config = PjsConfig::high_throughput();
212 assert_eq!(config.streaming.max_frame_size, 256 * 1024);
213 assert!(config.parser.enable_semantics);
214 assert!(config.simd.enable_stats);
215 }
216
217 #[test]
218 fn test_mobile_profile() {
219 let config = PjsConfig::mobile();
220 assert_eq!(config.streaming.max_frame_size, 8 * 1024);
221 assert_eq!(config.compression.string_dict_threshold, 25.0);
222 assert_eq!(config.simd.vectorized_chunk_size, 8);
223 }
224
225 #[test]
226 fn test_compression_with_custom_config() {
227 use crate::compression::{SchemaAnalyzer, CompressionConfig};
228 use serde_json::json;
229
230 let compression_config = CompressionConfig {
232 string_dict_threshold: 10.0, min_frequency_count: 1,
234 ..Default::default()
235 };
236
237 let mut analyzer = SchemaAnalyzer::with_config(compression_config);
238
239 let data = json!({
241 "users": [
242 {"status": "active", "role": "user"},
243 {"status": "active", "role": "user"}
244 ]
245 });
246
247 let strategy = analyzer.analyze(&data).unwrap();
248
249 match strategy {
251 crate::compression::CompressionStrategy::Dictionary { .. } |
252 crate::compression::CompressionStrategy::Hybrid { .. } => {
253 },
255 _ => {
256 }
258 }
259 }
260}