1pub struct ReplayWindow {
12 max_seq: Option<u32>,
14 window: u32,
16 bitmap: u64,
18}
19
20impl ReplayWindow {
21 pub fn new(window: u32) -> Self {
23 Self {
24 max_seq: None,
25 window: std::cmp::min(window, 64),
26 bitmap: 0,
27 }
28 }
29
30 pub fn check(&mut self, seq: u32) -> bool {
32 if self.max_seq.is_none() {
33 self.max_seq = Some(seq);
34 self.bitmap = 1;
35 return true;
36 }
37
38 let max = self.max_seq.unwrap();
39
40 let is_ahead = if seq > max {
41 true
42 } else if seq == max {
43 false
44 } else {
45 (max as u64) - (seq as u64) > (1u64 << 31)
46 };
47
48 if is_ahead && seq != max {
49 let forward_dist = if seq > max {
50 seq.wrapping_sub(max)
51 } else {
52 seq.wrapping_add(1)
53 };
54
55 if forward_dist >= 64 {
56 self.bitmap = 0;
57 } else {
58 self.bitmap <<= forward_dist;
59 }
60 self.max_seq = Some(seq);
61 self.bitmap |= 1;
62 return true;
63 }
64
65 if seq == max {
66 return (self.bitmap & 1) == 0;
67 }
68
69 let backward_dist = max.wrapping_sub(seq);
70
71 if backward_dist > self.window {
72 return false;
73 }
74
75 if backward_dist >= 64 {
76 return true;
77 }
78
79 let bit = 1u64 << backward_dist;
80 if (self.bitmap & bit) != 0 {
81 return false;
82 }
83
84 self.bitmap |= bit;
85 true
86 }
87}