summaryrefslogtreecommitdiffstats
path: root/openpgp/src/lib.rs
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/lib.rs
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/lib.rs')
-rw-r--r--openpgp/src/lib.rs19
1 files changed, 19 insertions, 0 deletions
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);