1use rand::prelude::*;
4use rand_chacha::ChaCha8Rng;
5
6pub struct SizeGen;
8
9impl SizeGen {
10 pub fn edge_cases() -> Vec<usize> {
12 vec![
13 0, 1, 2, 3, 7, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257, 511,
14 512, 513, 1023, 1024, 1025, 2047, 2048, 2049, 4095, 4096, 4097, 8191, 8192, 8193,
15 16383, 16384, 16385, 32767, 32768, 32769, 65535, 65536, 65537,
16 ]
17 }
18
19 pub fn near_i32_max() -> Vec<usize> {
21 vec![
22 (i32::MAX as usize) - 2,
23 (i32::MAX as usize) - 1,
24 i32::MAX as usize,
25 ]
26 }
27
28 pub fn primes() -> Vec<usize> {
30 vec![
31 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
32 89, 97, 101, 103, 107, 127, 131, 251, 257, 509, 521, 1021, 1031, 2039, 2053, 4093,
33 4099, 8191, 8209, 16381, 16411, 32749, 32771, 65521, 65537,
34 ]
35 }
36
37 pub fn random(count: usize, min: usize, max: usize, seed: u64) -> Vec<usize> {
39 let mut rng = ChaCha8Rng::seed_from_u64(seed);
40 (0..count).map(|_| rng.gen_range(min..=max)).collect()
41 }
42
43 pub fn warp_related() -> Vec<usize> {
45 vec![
46 31, 32, 33, 63, 64, 65, 95, 96, 97, 127, 128, 129, 159, 160, 161, 191, 192, 193, 223,
47 224, 225, 255, 256, 257, 287, 288, 289,
48 ]
49 }
50
51 pub fn block_related() -> Vec<usize> {
53 vec![
54 255, 256, 257, 511, 512, 513, 767, 768, 769, 1023, 1024, 1025, 1279, 1280, 1281, 1535,
55 1536, 1537,
56 ]
57 }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum Distribution {
63 AllEqual,
64 AllUnique,
65 Sorted,
66 ReverseSorted,
67 Alternating,
68 AdversarialHash,
69 Random,
70 HalfAndHalf,
71 Sparse,
72 Dense,
73}
74
75impl Distribution {
76 pub fn all() -> Vec<Distribution> {
78 vec![
79 Distribution::AllEqual,
80 Distribution::AllUnique,
81 Distribution::Sorted,
82 Distribution::ReverseSorted,
83 Distribution::Alternating,
84 Distribution::AdversarialHash,
85 Distribution::Random,
86 ]
87 }
88
89 pub fn generate_u32(&self, count: usize, seed: u64) -> Vec<u32> {
91 let mut rng = ChaCha8Rng::seed_from_u64(seed);
92 match self {
93 Distribution::AllEqual => vec![42u32; count],
94 Distribution::AllUnique => (0..count as u32).collect(),
95 Distribution::Sorted => (0..count as u32).collect(),
96 Distribution::ReverseSorted => (0..count as u32).rev().collect(),
97 Distribution::Alternating => (0..count)
98 .map(|i| if i % 2 == 0 { 0 } else { u32::MAX })
99 .collect(),
100 Distribution::AdversarialHash => (0..count).map(|i| (i as u32) * 256).collect(),
101 Distribution::Random => (0..count).map(|_| rng.gen()).collect(),
102 Distribution::HalfAndHalf => (0..count)
103 .map(|i| if i < count / 2 { 0 } else { 1 })
104 .collect(),
105 Distribution::Sparse => (0..count)
106 .map(|i| if i % 10 == 0 { 1 } else { 0 })
107 .collect(),
108 Distribution::Dense => (0..count)
109 .map(|i| if i % 10 == 0 { 0 } else { 1 })
110 .collect(),
111 }
112 }
113
114 pub fn generate_i64(&self, count: usize, seed: u64) -> Vec<i64> {
116 let mut rng = ChaCha8Rng::seed_from_u64(seed);
117 match self {
118 Distribution::AllEqual => vec![42i64; count],
119 Distribution::AllUnique => (0..count as i64).collect(),
120 Distribution::Sorted => (0..count as i64).collect(),
121 Distribution::ReverseSorted => (0..count as i64).rev().collect(),
122 Distribution::Alternating => (0..count)
123 .map(|i| if i % 2 == 0 { i64::MIN } else { i64::MAX })
124 .collect(),
125 Distribution::AdversarialHash => (0..count).map(|i| (i as i64) * 256).collect(),
126 Distribution::Random => (0..count).map(|_| rng.gen()).collect(),
127 Distribution::HalfAndHalf => (0..count)
128 .map(|i| if i < count / 2 { -1 } else { 1 })
129 .collect(),
130 Distribution::Sparse => (0..count)
131 .map(|i| if i % 10 == 0 { 1 } else { 0 })
132 .collect(),
133 Distribution::Dense => (0..count)
134 .map(|i| if i % 10 == 0 { 0 } else { 1 })
135 .collect(),
136 }
137 }
138
139 pub fn generate_f64(&self, count: usize, seed: u64) -> Vec<f64> {
141 let mut rng = ChaCha8Rng::seed_from_u64(seed);
142 match self {
143 Distribution::AllEqual => vec![42.0f64; count],
144 Distribution::AllUnique => (0..count).map(|i| i as f64).collect(),
145 Distribution::Sorted => (0..count).map(|i| i as f64).collect(),
146 Distribution::ReverseSorted => (0..count).map(|i| (count - 1 - i) as f64).collect(),
147 Distribution::Alternating => (0..count)
148 .map(|i| if i % 2 == 0 { f64::MIN } else { f64::MAX })
149 .collect(),
150 Distribution::AdversarialHash => (0..count).map(|i| (i as f64) * 256.0).collect(),
151 Distribution::Random => (0..count).map(|_| rng.gen_range(-1e10..1e10)).collect(),
152 Distribution::HalfAndHalf => (0..count)
153 .map(|i| if i < count / 2 { -1.0 } else { 1.0 })
154 .collect(),
155 Distribution::Sparse => (0..count)
156 .map(|i| if i % 10 == 0 { 1.0 } else { 0.0 })
157 .collect(),
158 Distribution::Dense => (0..count)
159 .map(|i| if i % 10 == 0 { 0.0 } else { 1.0 })
160 .collect(),
161 }
162 }
163
164 pub fn generate_mask(&self, count: usize, seed: u64) -> Vec<u8> {
166 let mut rng = ChaCha8Rng::seed_from_u64(seed);
167 match self {
168 Distribution::AllEqual => vec![1u8; count],
169 Distribution::AllUnique => (0..count).map(|i| (i % 2) as u8).collect(),
170 Distribution::Sorted => (0..count)
171 .map(|i| if i < count / 2 { 0 } else { 1 })
172 .collect(),
173 Distribution::ReverseSorted => (0..count)
174 .map(|i| if i < count / 2 { 1 } else { 0 })
175 .collect(),
176 Distribution::Alternating => (0..count).map(|i| (i % 2) as u8).collect(),
177 Distribution::AdversarialHash => (0..count).map(|i| (i % 2) as u8).collect(),
178 Distribution::Random => (0..count)
179 .map(|_| if rng.gen_bool(0.5) { 1 } else { 0 })
180 .collect(),
181 Distribution::HalfAndHalf => (0..count)
182 .map(|i| if i < count / 2 { 0 } else { 1 })
183 .collect(),
184 Distribution::Sparse => (0..count)
185 .map(|i| if i % 10 == 0 { 1 } else { 0 })
186 .collect(),
187 Distribution::Dense => (0..count)
188 .map(|i| if i % 10 == 0 { 0 } else { 1 })
189 .collect(),
190 }
191 }
192}
193
194pub struct NumericEdges;
196
197impl NumericEdges {
198 pub fn u32_edges() -> Vec<u32> {
199 vec![0, 1, 2, u32::MAX - 1, u32::MAX]
200 }
201
202 pub fn i32_edges() -> Vec<i32> {
203 vec![i32::MIN, i32::MIN + 1, -1, 0, 1, i32::MAX - 1, i32::MAX]
204 }
205
206 pub fn u64_edges() -> Vec<u64> {
207 vec![0, 1, 2, u64::MAX - 1, u64::MAX]
208 }
209
210 pub fn i64_edges() -> Vec<i64> {
211 vec![i64::MIN, i64::MIN + 1, -1, 0, 1, i64::MAX - 1, i64::MAX]
212 }
213
214 pub fn f32_edges() -> Vec<f32> {
215 vec![
216 f32::NEG_INFINITY,
217 f32::MIN,
218 -1.0,
219 -f32::MIN_POSITIVE,
220 -0.0,
221 0.0,
222 f32::MIN_POSITIVE,
223 1.0,
224 f32::MAX,
225 f32::INFINITY,
226 f32::NAN,
227 ]
228 }
229
230 pub fn f64_edges() -> Vec<f64> {
231 vec![
232 f64::NEG_INFINITY,
233 f64::MIN,
234 -1.0,
235 -f64::MIN_POSITIVE,
236 -0.0,
237 0.0,
238 f64::MIN_POSITIVE,
239 1.0,
240 f64::MAX,
241 f64::INFINITY,
242 f64::NAN,
243 ]
244 }
245
246 pub fn f64_subnormals() -> Vec<f64> {
247 vec![
248 5e-324,
249 1e-323,
250 1e-320,
251 1e-310,
252 f64::MIN_POSITIVE / 2.0,
253 -5e-324,
254 -1e-323,
255 -f64::MIN_POSITIVE / 2.0,
256 ]
257 }
258
259 pub fn f64_fma_stress() -> Vec<(f64, f64, f64)> {
260 vec![
261 (1.0 + 1e-15, 1.0 - 1e-15, 1e-30),
262 (1e100, 1e100, 1e-100),
263 (1e-100, 1e-100, 1e-200),
264 (f64::MAX / 2.0, 2.0, -f64::MAX),
265 ]
266 }
267}
268
269pub struct AlignmentGen;
271
272impl AlignmentGen {
273 pub fn offsets() -> Vec<(usize, &'static str)> {
274 vec![
275 (0, "aligned"),
276 (1, "off-by-1"),
277 (2, "off-by-2"),
278 (3, "off-by-3"),
279 (4, "off-by-4"),
280 (5, "off-by-5"),
281 (6, "off-by-6"),
282 (7, "off-by-7"),
283 ]
284 }
285
286 pub fn violating_offsets(required_alignment: usize) -> Vec<usize> {
287 (1..required_alignment).collect()
288 }
289}
290
291pub struct KeyDistribution;
293
294impl KeyDistribution {
295 pub fn join_test_data(
297 size: usize,
298 overlap_ratio: f64,
299 seed: u64,
300 ) -> (Vec<u32>, Vec<u32>, usize) {
301 let mut rng = ChaCha8Rng::seed_from_u64(seed);
302 let overlap_size = (size as f64 * overlap_ratio) as usize;
303 let common: Vec<u32> = (0..overlap_size as u32).collect();
304 let left_only: Vec<u32> = (overlap_size as u32..(size as u32)).collect();
305 let right_only: Vec<u32> = ((size + overlap_size) as u32..((2 * size) as u32)).collect();
306
307 let mut left = common.clone();
308 left.extend(left_only);
309 left.shuffle(&mut rng);
310
311 let mut right = common.clone();
312 right.extend(right_only);
313 right.shuffle(&mut rng);
314
315 (left, right, overlap_size)
316 }
317
318 pub fn collision_keys(count: usize, collision_factor: usize) -> Vec<u32> {
320 (0..count).map(|i| (i * collision_factor) as u32).collect()
321 }
322
323 pub fn groupby_keys(total_rows: usize, num_groups: usize, seed: u64) -> Vec<u32> {
325 let mut rng = ChaCha8Rng::seed_from_u64(seed);
326 (0..total_rows)
327 .map(|_| rng.gen_range(0..num_groups as u32))
328 .collect()
329 }
330}