Skip to content

Commit

Permalink
bgzf/writer: Reuse a compressed data buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed May 6, 2024
1 parent d9dfa33 commit 8196609
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
22 changes: 12 additions & 10 deletions noodles-bgzf/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ where
{
inner: Option<W>,
position: u64,
buf: Vec<u8>,
staging_buf: Vec<u8>,
compression_buf: Vec<u8>,
compression_level: CompressionLevelImpl,
}

Expand Down Expand Up @@ -151,22 +152,23 @@ where
/// ```
pub fn virtual_position(&self) -> VirtualPosition {
// SAFETY: The uncompressed buffer is guaranteed to be <= `MAX_UNCOMPRESSED_POSITION`.
let uncompressed_position = self.buf.len() as u16;
let uncompressed_position = self.staging_buf.len() as u16;
VirtualPosition::try_from((self.position, uncompressed_position)).unwrap()
}

fn flush_block(&mut self) -> io::Result<()> {
use crate::deflate;

let mut cdata = Vec::new();
let crc32 = deflate::encode(&self.buf, self.compression_level, &mut cdata)?;
let compressed_data = &mut self.compression_buf;
let crc32 = deflate::encode(&self.staging_buf, self.compression_level, compressed_data)?;

let inner = self.inner.as_mut().unwrap();
let block_size = write_frame(inner, &cdata, crc32, self.buf.len())?;
let uncompressed_len = self.staging_buf.len();
let block_size = write_frame(inner, compressed_data, crc32, uncompressed_len)?;

self.position += block_size as u64;

self.buf.clear();
self.staging_buf.clear();

Ok(())
}
Expand Down Expand Up @@ -237,19 +239,19 @@ where
W: Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let max_write_len = cmp::min(MAX_BUF_SIZE - self.buf.len(), buf.len());
let max_write_len = cmp::min(MAX_BUF_SIZE - self.staging_buf.len(), buf.len());

self.buf.extend_from_slice(&buf[..max_write_len]);
self.staging_buf.extend_from_slice(&buf[..max_write_len]);

if self.buf.len() >= MAX_BUF_SIZE {
if self.staging_buf.len() >= MAX_BUF_SIZE {
self.flush()?;
}

Ok(max_write_len)
}

fn flush(&mut self) -> io::Result<()> {
if self.buf.is_empty() {
if self.staging_buf.is_empty() {
Ok(())
} else {
self.flush_block()
Expand Down
3 changes: 2 additions & 1 deletion noodles-bgzf/src/writer/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl Builder {
Writer {
inner: Some(writer),
position: 0,
buf: Vec::with_capacity(MAX_BUF_SIZE),
staging_buf: Vec::with_capacity(MAX_BUF_SIZE),
compression_buf: Vec::new(),
compression_level: self.compression_level.into(),
}
}
Expand Down

0 comments on commit 8196609

Please sign in to comment.