summaryrefslogtreecommitdiffstats
path: root/openpgp/src/parse
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-11-03 14:48:08 +0100
committerJustus Winter <justus@sequoia-pgp.org>2021-11-03 14:48:08 +0100
commitfc6aee27f21f94eeecd3b495f0f45ffaa2203579 (patch)
tree4f7d65023d5f5f673cedd36466d264bb642c566c /openpgp/src/parse
parenta3c77e3fff771b168b53bd9b3a69c31a6775857b (diff)
openpgp: Recycle buffers.
- Previously, we spent a considerable amount of time callocing new buffers.
Diffstat (limited to 'openpgp/src/parse')
-rw-r--r--openpgp/src/parse/partial_body.rs19
1 files changed, 14 insertions, 5 deletions
diff --git a/openpgp/src/parse/partial_body.rs b/openpgp/src/parse/partial_body.rs
index bd9a26c8..896d5555 100644
--- a/openpgp/src/parse/partial_body.rs
+++ b/openpgp/src/parse/partial_body.rs
@@ -5,7 +5,7 @@ use std::io::{Error, ErrorKind};
use buffered_reader::{buffered_reader_generic_read_impl, BufferedReader};
-use crate::vec_truncate;
+use crate::{vec_resize, vec_truncate};
use crate::packet::header::BodyLength;
use crate::parse::{Cookie, Hashing};
@@ -29,9 +29,11 @@ pub(crate) struct BufferedReaderPartialBodyFilter<T: BufferedReader<Cookie>> {
// Sometimes we have to double buffer. This happens if the caller
// requests X bytes and that chunk straddles a partial body length
// boundary.
- buffer: Option<Box<[u8]>>,
+ buffer: Option<Vec<u8>>,
// The position within the buffer.
cursor: usize,
+ /// Currently unused buffer.
+ unused_buffer: Option<Vec<u8>>,
// The user-defined cookie.
cookie: Cookie,
@@ -79,6 +81,7 @@ impl<T: BufferedReader<Cookie>> BufferedReaderPartialBodyFilter<T> {
last: false,
buffer: None,
cursor: 0,
+ unused_buffer: None,
cookie,
hash_headers,
}
@@ -94,7 +97,12 @@ impl<T: BufferedReader<Cookie>> BufferedReaderPartialBodyFilter<T> {
// We want to avoid double buffering as much as possible.
// Thus, we only buffer as much as needed.
- let mut buffer = vec![0; amount];
+ let mut buffer = self.unused_buffer.take()
+ .map(|mut v| {
+ vec_resize(&mut v, amount);
+ v
+ })
+ .unwrap_or_else(|| vec![0u8; amount]);
let mut amount_buffered = 0;
if let Some(ref old_buffer) = self.buffer {
@@ -206,10 +214,11 @@ impl<T: BufferedReader<Cookie>> BufferedReaderPartialBodyFilter<T> {
}
}
vec_truncate(&mut buffer, amount_buffered);
- buffer.shrink_to_fit();
// We're done.
- self.buffer = Some(buffer.into_boxed_slice());
+
+ self.unused_buffer = self.buffer.take();
+ self.buffer = Some(buffer);
self.cursor = 0;
if let Some(err) = err {