1pub mod security;
7
8use crate::compression::CompressionConfig;
9pub use security::SecurityConfig;
10
11#[derive(Debug, Clone, Default)]
13pub struct PjsConfig {
14 pub security: SecurityConfig,
16 pub compression: CompressionConfig,
18 pub parser: ParserConfig,
20 pub streaming: StreamingConfig,
22 pub simd: SimdConfig,
24}
25
26#[derive(Debug, Clone)]
28pub struct ParserConfig {
29 pub max_input_size_mb: usize,
31 pub buffer_initial_capacity: usize,
33 pub simd_min_size: usize,
35 pub enable_semantics: bool,
37}
38
39#[derive(Debug, Clone)]
41pub struct StreamingConfig {
42 pub max_frame_size: usize,
44 pub default_chunk_size: usize,
46 pub operation_timeout_ms: u64,
48 pub max_bandwidth_bps: u64,
50}
51
52#[derive(Debug, Clone)]
54pub struct SimdConfig {
55 pub batch_size: usize,
57 pub initial_capacity: usize,
59 pub avx512_alignment: usize,
61 pub vectorized_chunk_size: usize,
63 pub enable_stats: bool,
65}
66
67impl Default for ParserConfig {
68 fn default() -> Self {
69 Self {
70 max_input_size_mb: 100,
71 buffer_initial_capacity: 8192, simd_min_size: 4096, enable_semantics: true,
74 }
75 }
76}
77
78impl Default for StreamingConfig {
79 fn default() -> Self {
80 Self {
81 max_frame_size: 64 * 1024, default_chunk_size: 1024,
83 operation_timeout_ms: 5000, max_bandwidth_bps: 1_000_000, }
86 }
87}
88
89impl Default for SimdConfig {
90 fn default() -> Self {
91 Self {
92 batch_size: 100,
93 initial_capacity: 8192, avx512_alignment: 64,
95 vectorized_chunk_size: 32,
96 enable_stats: false,
97 }
98 }
99}
100
101impl PjsConfig {
103 pub fn low_latency() -> Self {
105 Self {
106 security: SecurityConfig::development(),
107 compression: CompressionConfig::default(),
108 parser: ParserConfig {
109 max_input_size_mb: 10,
110 buffer_initial_capacity: 4096, simd_min_size: 2048, enable_semantics: false, },
114 streaming: StreamingConfig {
115 max_frame_size: 16 * 1024, default_chunk_size: 512,
117 operation_timeout_ms: 1000, max_bandwidth_bps: 10_000_000, },
120 simd: SimdConfig {
121 batch_size: 50,
122 initial_capacity: 4096, avx512_alignment: 64,
124 vectorized_chunk_size: 16,
125 enable_stats: false,
126 },
127 }
128 }
129
130 pub fn high_throughput() -> Self {
132 Self {
133 security: SecurityConfig::high_throughput(),
134 compression: CompressionConfig::default(),
135 parser: ParserConfig {
136 max_input_size_mb: 1000, buffer_initial_capacity: 32768, simd_min_size: 8192, enable_semantics: true,
140 },
141 streaming: StreamingConfig {
142 max_frame_size: 256 * 1024, default_chunk_size: 4096,
144 operation_timeout_ms: 30000, max_bandwidth_bps: 100_000_000, },
147 simd: SimdConfig {
148 batch_size: 500,
149 initial_capacity: 32768, avx512_alignment: 64,
151 vectorized_chunk_size: 64,
152 enable_stats: true,
153 },
154 }
155 }
156
157 pub fn mobile() -> Self {
159 Self {
160 security: SecurityConfig::low_memory(),
161 compression: CompressionConfig {
162 min_array_length: 1,
163 min_string_length: 2,
164 min_frequency_count: 1,
165 uuid_compression_potential: 0.5,
166 string_dict_threshold: 25.0, delta_threshold: 15.0, min_delta_potential: 0.2,
169 run_length_threshold: 10.0, min_compression_potential: 0.3,
171 min_numeric_sequence_size: 2,
172 },
173 parser: ParserConfig {
174 max_input_size_mb: 10,
175 buffer_initial_capacity: 2048, simd_min_size: 1024, enable_semantics: false,
178 },
179 streaming: StreamingConfig {
180 max_frame_size: 8 * 1024, default_chunk_size: 256,
182 operation_timeout_ms: 10000, max_bandwidth_bps: 100_000, },
185 simd: SimdConfig {
186 batch_size: 25,
187 initial_capacity: 2048, avx512_alignment: 32, vectorized_chunk_size: 8,
190 enable_stats: false,
191 },
192 }
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199
200 #[test]
201 fn test_default_config() {
202 let config = PjsConfig::default();
203 assert_eq!(config.parser.max_input_size_mb, 100);
204 assert_eq!(config.streaming.max_frame_size, 64 * 1024);
205 assert_eq!(config.simd.batch_size, 100);
206 }
207
208 #[test]
209 fn test_low_latency_profile() {
210 let config = PjsConfig::low_latency();
211 assert_eq!(config.streaming.max_frame_size, 16 * 1024);
212 assert!(!config.parser.enable_semantics);
213 assert_eq!(config.streaming.operation_timeout_ms, 1000);
214 }
215
216 #[test]
217 fn test_high_throughput_profile() {
218 let config = PjsConfig::high_throughput();
219 assert_eq!(config.streaming.max_frame_size, 256 * 1024);
220 assert!(config.parser.enable_semantics);
221 assert!(config.simd.enable_stats);
222 }
223
224 #[test]
225 fn test_mobile_profile() {
226 let config = PjsConfig::mobile();
227 assert_eq!(config.streaming.max_frame_size, 8 * 1024);
228 assert_eq!(config.compression.string_dict_threshold, 25.0);
229 assert_eq!(config.simd.vectorized_chunk_size, 8);
230 }
231
232 #[test]
233 fn test_compression_with_custom_config() {
234 use crate::compression::{CompressionConfig, SchemaAnalyzer};
235 use serde_json::json;
236
237 let compression_config = CompressionConfig {
239 string_dict_threshold: 10.0, min_frequency_count: 1,
241 ..Default::default()
242 };
243
244 let mut analyzer = SchemaAnalyzer::with_config(compression_config);
245
246 let data = json!({
248 "users": [
249 {"status": "active", "role": "user"},
250 {"status": "active", "role": "user"}
251 ]
252 });
253
254 let strategy = analyzer.analyze(&data).unwrap();
255
256 match strategy {
258 crate::compression::CompressionStrategy::Dictionary { .. }
259 | crate::compression::CompressionStrategy::Hybrid { .. } => {
260 }
262 _ => {
263 }
265 }
266 }
267}