1#![cfg(feature = "pigz")]
2use crate::{Chunk, ChunkIncr, ToChunkIncr};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct PigzRsyncable {
6 bits: u8,
7
8 mask: u32,
10 hit: u32,
12}
13
14impl PigzRsyncable {
15 pub fn with_bits(bits: u8) -> PigzRsyncable {
16 let mask = (1 << bits) - 1;
17 let hit = mask >> 1;
18 PigzRsyncable { bits, mask, hit }
19 }
20}
21
22impl Default for PigzRsyncable {
23 fn default() -> Self {
24 Self::with_bits(12)
25 }
26}
27
28impl Chunk for PigzRsyncable {
29 type SearchState = PigzRsyncableSearchState;
30
31 fn to_search_state(&self) -> Self::SearchState {
32 self.into()
33 }
34
35 fn find_chunk_edge(
36 &self,
37 state: &mut Self::SearchState,
38 data: &[u8],
39 ) -> (Option<usize>, usize) {
40 for i in 0..data.len() {
41 let v = data[i];
42
43 if state.state.add(self, v) {
44 *state = self.to_search_state();
45 return (Some(i + 1), i + 1);
46 }
47 }
48
49 (None, data.len())
50 }
51}
52
53impl From<&PigzRsyncable> for PigzRsyncableIncr {
54 fn from(src: &PigzRsyncable) -> Self {
55 src.clone().into()
56 }
57}
58
59impl ToChunkIncr for PigzRsyncable {
60 type Incr = PigzRsyncableIncr;
61 fn to_chunk_incr(&self) -> Self::Incr {
62 self.into()
63 }
64}
65
66#[derive(Debug, Clone)]
67struct PigzRsyncableState {
68 hash: u32,
69}
70
71impl From<&PigzRsyncable> for PigzRsyncableState {
72 fn from(params: &PigzRsyncable) -> Self {
73 PigzRsyncableState { hash: params.hit }
74 }
75}
76
77#[derive(Debug, Clone)]
81pub struct PigzRsyncableSearchState {
82 state: PigzRsyncableState,
83}
84
85impl From<&PigzRsyncable> for PigzRsyncableSearchState {
86 fn from(params: &PigzRsyncable) -> Self {
87 PigzRsyncableSearchState {
88 state: params.into(),
89 }
90 }
91}
92
93#[derive(Debug, Clone)]
101pub struct PigzRsyncableIncr {
102 params: PigzRsyncable,
103 state: PigzRsyncableState,
104}
105
106impl PigzRsyncableIncr {}
107
108impl From<PigzRsyncable> for PigzRsyncableIncr {
109 fn from(params: PigzRsyncable) -> Self {
110 let state = (¶ms).into();
111 PigzRsyncableIncr { params, state }
112 }
113}
114
115impl PigzRsyncableState {
116 fn add(&mut self, parent: &PigzRsyncable, v: u8) -> bool {
117 self.hash = ((self.hash << 1) ^ (v as u32)) & parent.mask;
118 self.hash == parent.hit
119 }
120}
121
122impl ChunkIncr for PigzRsyncableIncr {
123 fn push(&mut self, data: &[u8]) -> Option<usize> {
124 for (i, &v) in data.iter().enumerate() {
125 if self.state.add(&self.params, v) {
126 self.state = (&self.params).into();
127 return Some(i + 1);
128 }
129 }
130
131 None
132 }
133}