loro_fractional_index/
jitter.rs1use std::sync::Arc;
2
3use crate::{new_after, new_before, new_between, FractionalIndex, TERMINATOR};
4use rand::Rng;
5
6impl FractionalIndex {
7 pub fn jitter_default(rng: &mut impl Rng, jitter: u8) -> Self {
8 Self::jitter(Vec::new(), rng, jitter)
9 }
10
11 pub fn new_jitter<R: Rng>(
12 lower: Option<&FractionalIndex>,
13 upper: Option<&FractionalIndex>,
14 rng: &mut R,
15 jitter: u8,
16 ) -> Option<Self> {
17 match (lower, upper) {
18 (Some(lower), Some(upper)) => Self::new_between_jitter(lower, upper, rng, jitter),
19 (Some(lower), None) => Self::new_after_jitter(lower, rng, jitter).into(),
20 (None, Some(upper)) => Self::new_before_jitter(upper, rng, jitter).into(),
21 (None, None) => FractionalIndex::jitter_default(rng, jitter).into(),
22 }
23 }
24
25 fn jitter<R: Rng>(mut bytes: Vec<u8>, rng: &mut R, jitter: u8) -> FractionalIndex {
26 bytes.push(TERMINATOR);
27 bytes.extend((0..jitter).map(|_| rng.gen::<u8>()));
28 FractionalIndex(Arc::new(bytes))
29 }
30
31 pub fn new_before_jitter<R: Rng>(
32 FractionalIndex(bytes): &FractionalIndex,
33 rng: &mut R,
34 jitter: u8,
35 ) -> Self {
36 Self::jitter(new_before(bytes), rng, jitter)
37 }
38
39 pub fn new_after_jitter<R: Rng>(
40 FractionalIndex(bytes): &FractionalIndex,
41 rng: &mut R,
42 jitter: u8,
43 ) -> Self {
44 Self::jitter(new_after(bytes), rng, jitter)
45 }
46
47 pub fn new_between_jitter<R: Rng>(
48 FractionalIndex(left): &FractionalIndex,
49 FractionalIndex(right): &FractionalIndex,
50 rng: &mut R,
51 jitter: u8,
52 ) -> Option<Self> {
53 new_between(left, right, jitter as usize + 1).map(|x| Self::jitter(x, rng, jitter))
54 }
55
56 pub fn generate_n_evenly_jitter<R: Rng>(
57 lower: Option<&FractionalIndex>,
58 upper: Option<&FractionalIndex>,
59 n: usize,
60 rng: &mut R,
61 jitter: u8,
62 ) -> Option<Vec<Self>> {
63 fn generate(
64 lower: Option<&FractionalIndex>,
65 upper: Option<&FractionalIndex>,
66 n: usize,
67 push: &mut impl FnMut(FractionalIndex),
68 rng: &mut impl Rng,
69 jitter: u8,
70 ) {
71 if n == 0 {
72 return;
73 }
74
75 let mid = n / 2;
76 let mid_ans = FractionalIndex::new_jitter(lower, upper, rng, jitter).unwrap();
77 if n == 1 {
78 push(mid_ans);
79 return;
80 }
81
82 generate(lower, Some(&mid_ans), mid, push, rng, jitter);
83 push(mid_ans.clone());
84 if n - mid - 1 == 0 {
85 return;
86 }
87 generate(Some(&mid_ans), upper, n - mid - 1, push, rng, jitter);
88 }
89
90 if n == 0 {
91 return Some(Vec::new());
92 }
93
94 match (lower, upper) {
95 (Some(a), Some(b)) if a >= b => return None,
96 _ => {}
97 }
98
99 let mut ans = Vec::with_capacity(n);
100 generate(lower, upper, n, &mut |v| ans.push(v), rng, jitter);
101 Some(ans)
102 }
103}