summaryrefslogtreecommitdiffstats
path: root/openpgp/src
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-01-24 13:32:50 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-01-24 13:32:50 +0100
commite9fcf9181f21cf7d687131e5aa191beb68a75a8e (patch)
treea184409916f77746fc24ca7086d4706aaef6dbf5 /openpgp/src
parenta3510fd98f5aabf26ce3d3c76b249090386279c4 (diff)
openpgp: Optimize drop(Vec<u8>::drain(..n)) in debug mode.
- Similar to Vec<u8>::truncate(_), this operation is very slow in debug mode due to the dropping of drained elements. Provide an optimized version in debug mode.
Diffstat (limited to 'openpgp/src')
-rw-r--r--openpgp/src/armor.rs4
-rw-r--r--openpgp/src/crypto/aead.rs4
-rw-r--r--openpgp/src/crypto/symmetric.rs4
-rw-r--r--openpgp/src/lib.rs19
-rw-r--r--openpgp/src/parse/stream.rs6
-rw-r--r--openpgp/src/serialize/partial_body.rs2
6 files changed, 29 insertions, 10 deletions
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs
index 5214d4a7..d690bfc5 100644
--- a/openpgp/src/armor.rs
+++ b/openpgp/src/armor.rs
@@ -1036,7 +1036,7 @@ impl<'a> Read for Reader<'a> {
let amount = cmp::min(buf.len(), self.buffer.len());
buf[..amount].copy_from_slice(&self.buffer[..amount]);
- self.buffer.drain(..amount);
+ crate::vec_drain_prefix(&mut self.buffer, amount);
(0, amount)
} else {
@@ -1111,7 +1111,7 @@ impl<'a> Read for Reader<'a> {
let copied = cmp::min(buf.len(), self.buffer.len());
buf[..copied].copy_from_slice(&self.buffer[..copied]);
- self.buffer.drain(..copied);
+ crate::vec_drain_prefix(&mut self.buffer, copied);
copied
} else {
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs
index 35fbd074..a297b999 100644
--- a/openpgp/src/crypto/aead.rs
+++ b/openpgp/src/crypto/aead.rs
@@ -223,7 +223,7 @@ impl<'a> Decryptor<'a> {
if self.buffer.len() > 0 {
let to_copy = cmp::min(self.buffer.len(), plaintext.len());
&plaintext[..to_copy].copy_from_slice(&self.buffer[..to_copy]);
- self.buffer.drain(..to_copy);
+ crate::vec_drain_prefix(&mut self.buffer, to_copy);
pos = to_copy;
if pos == plaintext.len() {
@@ -341,7 +341,7 @@ impl<'a> Decryptor<'a> {
&plaintext[pos..pos + to_copy]
.copy_from_slice(&self.buffer[..to_copy]);
- self.buffer.drain(..to_copy);
+ crate::vec_drain_prefix(&mut self.buffer, to_copy);
pos += to_copy;
} else {
pos += to_decrypt;
diff --git a/openpgp/src/crypto/symmetric.rs b/openpgp/src/crypto/symmetric.rs
index b6aa799b..fb889dd4 100644
--- a/openpgp/src/crypto/symmetric.rs
+++ b/openpgp/src/crypto/symmetric.rs
@@ -205,7 +205,7 @@ impl<R: io::Read> io::Read for Decryptor<R> {
if self.buffer.len() > 0 {
let to_copy = cmp::min(self.buffer.len(), plaintext.len());
&plaintext[..to_copy].copy_from_slice(&self.buffer[..to_copy]);
- self.buffer.drain(..to_copy);
+ crate::vec_drain_prefix(&mut self.buffer, to_copy);
pos = to_copy;
}
@@ -274,7 +274,7 @@ impl<R: io::Read> io::Read for Decryptor<R> {
format!("{}", e)))?;
&plaintext[pos..pos + to_copy].copy_from_slice(&self.buffer[..to_copy]);
- self.buffer.drain(..to_copy);
+ crate::vec_drain_prefix(&mut self.buffer, to_copy);
pos += to_copy;
diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs
index f1d1506e..0bc4b3d2 100644
--- a/openpgp/src/lib.rs
+++ b/openpgp/src/lib.rs
@@ -90,6 +90,25 @@ fn vec_truncate(v: &mut Vec<u8>, len: usize) {
}
}
+/// Like `drop(Vec<u8>::drain(..prefix_len))`, but fast in debug
+/// builds.
+fn vec_drain_prefix(v: &mut Vec<u8>, prefix_len: usize) {
+ if cfg!(debug_assertions) {
+ // Panic like v.drain(..prefix_len).
+ assert!(prefix_len <= v.len(), "prefix len {} > vector len {}",
+ prefix_len, v.len());
+ let new_len = v.len() - prefix_len;
+ unsafe {
+ std::ptr::copy(v[prefix_len..].as_ptr(),
+ v[..].as_mut_ptr(),
+ new_len);
+ }
+ vec_truncate(v, new_len);
+ } else {
+ v.drain(..prefix_len);
+ }
+}
+
// Like assert!, but checks a pattern.
//
// assert_match!(Some(_) = x);
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index 61c12915..1b939c5b 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -895,7 +895,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> {
let n = cmp::min(buf.len(), reserve.len());
&mut buf[..n].copy_from_slice(&reserve[..n]);
- reserve.drain(..n);
+ crate::vec_drain_prefix(reserve, n);
return Ok(n);
}
@@ -1091,7 +1091,7 @@ impl<'a> Transformer<'a> {
let n = cmp::min(buf.len(), self.buffer.len());
&mut buf[..n].copy_from_slice(&self.buffer[..n]);
- self.buffer.drain(..n);
+ crate::vec_drain_prefix(&mut self.buffer, n);
Ok(n)
}
}
@@ -1809,7 +1809,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
let n = cmp::min(buf.len(), reserve.len());
&mut buf[..n].copy_from_slice(&reserve[..n]);
- reserve.drain(..n);
+ crate::vec_drain_prefix(reserve, n);
return Ok(n);
}
diff --git a/openpgp/src/serialize/partial_body.rs b/openpgp/src/serialize/partial_body.rs
index 26bb0e14..b85b8b9c 100644
--- a/openpgp/src/serialize/partial_body.rs
+++ b/openpgp/src/serialize/partial_body.rs
@@ -138,7 +138,7 @@ impl<'a, C: 'a> PartialBodyFilter<'a, C> {
// ... from our buffer first...
let l = cmp::min(self.buffer.len(), chunk_size);
inner.write_all(&self.buffer[..l])?;
- self.buffer.drain(..l);
+ crate::vec_drain_prefix(&mut self.buffer, l);
// ... then from other.
if chunk_size > l {