Skip to content

Commit 9e3774f

Browse files
committed
refactor: drain buffer inside write
1 parent 1aba65b commit 9e3774f

File tree

3 files changed

+38
-60
lines changed

3 files changed

+38
-60
lines changed

src/codec/lz4/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,6 @@ impl Decode for Lz4Decoder {
8888
&mut self,
8989
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
9090
) -> Result<bool> {
91-
Ok(true)
91+
self.flush(output)
9292
}
9393
}

src/codec/lz4/encoder.rs

Lines changed: 32 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ impl Lz4Encoder {
8989
self.block_buffer_size
9090
}
9191

92+
fn drain_buffer(
93+
&mut self,
94+
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
95+
) -> (usize, usize) {
96+
match self.maybe_buffer.as_mut() {
97+
Some(buffer) => {
98+
let drained_bytes = output.copy_unwritten_from(buffer);
99+
(drained_bytes, buffer.unwritten().len())
100+
}
101+
None => (0, 0),
102+
}
103+
}
104+
92105
fn write<'a, T>(
93106
&'a mut self,
94107
lz4_fn: Lz4Fn<'a, T>,
@@ -97,6 +110,11 @@ impl Lz4Encoder {
97110
where
98111
T: AsRef<[u8]>,
99112
{
113+
let (drained_before, undrained) = self.drain_buffer(output);
114+
if undrained > 0 {
115+
return Ok(drained_before);
116+
}
117+
100118
let min_dst_size = match &lz4_fn {
101119
Lz4Fn::Begin => LZ4F_HEADER_SIZE_MAX,
102120
Lz4Fn::Update { input } => {
@@ -169,8 +187,9 @@ impl Lz4Encoder {
169187
}
170188
};
171189

172-
if direct_output {
190+
let drained_after = if direct_output {
173191
output.advance(len);
192+
len
174193
} else {
175194
// SAFETY: buffer is initialized above incase of a non-direct operation
176195
unsafe {
@@ -180,9 +199,11 @@ impl Lz4Encoder {
180199
.get_mut()
181200
.set_len(len);
182201
}
183-
}
202+
let (d, _) = self.drain_buffer(output);
203+
d
204+
};
184205

185-
Ok(len)
206+
Ok(drained_before + drained_after)
186207
}
187208
}
188209

@@ -199,18 +220,7 @@ impl Encode for Lz4Encoder {
199220
}
200221

201222
State::Encoding => {
202-
if let Some(buffer) = self.maybe_buffer.as_mut() {
203-
output.copy_unwritten_from(buffer);
204-
}
205-
206-
// start another round of compression if buffer is fully drained or None
207-
if self
208-
.maybe_buffer
209-
.as_ref()
210-
.is_none_or(|buffer| buffer.unwritten().is_empty())
211-
{
212-
self.write(Lz4Fn::Update { input }, output)?;
213-
}
223+
self.write(Lz4Fn::Update { input }, output)?;
214224
}
215225

216226
State::Footer | State::Done => {
@@ -236,32 +246,13 @@ impl Encode for Lz4Encoder {
236246
}
237247

238248
State::Encoding => {
239-
if let Some(buffer) = self.maybe_buffer.as_mut() {
240-
output.copy_unwritten_from(buffer);
241-
}
242-
243-
if self
244-
.maybe_buffer
245-
.as_ref()
246-
.is_none_or(|buffer| buffer.unwritten().is_empty())
247-
{
248-
let len = self.write(Lz4Fn::Flush::<&[u8]>, output)?;
249-
len == 0
250-
} else {
251-
false
252-
}
249+
let len = self.write(Lz4Fn::Flush::<&[u8]>, output)?;
250+
len == 0
253251
}
254252

255253
State::Footer => {
256-
if let Some(buffer) = self.maybe_buffer.as_mut() {
257-
output.copy_unwritten_from(buffer);
258-
}
259-
260-
if self
261-
.maybe_buffer
262-
.as_ref()
263-
.is_none_or(|buffer| buffer.unwritten().is_empty())
264-
{
254+
let (_, undrained) = self.drain_buffer(output);
255+
if undrained == 0 {
265256
self.state = State::Done;
266257
true
267258
} else {
@@ -293,29 +284,12 @@ impl Encode for Lz4Encoder {
293284
}
294285

295286
State::Encoding => {
296-
if let Some(buffer) = self.maybe_buffer.as_mut() {
297-
output.copy_unwritten_from(buffer);
298-
}
299-
300-
if self
301-
.maybe_buffer
302-
.as_ref()
303-
.is_none_or(|buffer| buffer.unwritten().is_empty())
304-
{
305-
self.write(Lz4Fn::End::<&[u8]>, output)?;
306-
}
287+
self.write(Lz4Fn::End::<&[u8]>, output)?;
307288
}
308289

309290
State::Footer => {
310-
if let Some(buffer) = self.maybe_buffer.as_mut() {
311-
output.copy_unwritten_from(buffer);
312-
}
313-
314-
if self
315-
.maybe_buffer
316-
.as_ref()
317-
.is_none_or(|buffer| buffer.unwritten().is_empty())
318-
{
291+
let (_, undrained) = self.drain_buffer(output);
292+
if undrained == 0 {
319293
self.state = State::Done;
320294
}
321295
}

src/util.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,17 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> PartialBuffer<B> {
4242
&mut self.buffer.as_mut()[self.index..]
4343
}
4444

45-
pub(crate) fn copy_unwritten_from<C: AsRef<[u8]>>(&mut self, other: &mut PartialBuffer<C>) {
45+
pub(crate) fn copy_unwritten_from<C: AsRef<[u8]>>(
46+
&mut self,
47+
other: &mut PartialBuffer<C>,
48+
) -> usize {
4649
let len = std::cmp::min(self.unwritten().len(), other.unwritten().len());
4750

4851
self.unwritten_mut()[..len].copy_from_slice(&other.unwritten()[..len]);
4952

5053
self.advance(len);
5154
other.advance(len);
55+
len
5256
}
5357
}
5458

0 commit comments

Comments
 (0)