summaryrefslogtreecommitdiffstats
path: root/openpgp/src/parse
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2019-11-07 11:48:23 +0100
committerNeal H. Walfield <neal@pep.foundation>2019-11-07 12:04:51 +0100
commit5bbd9b88f6c49f7e22a6bc817b8bdf251565f460 (patch)
tree60f994707b87fc919c85040ef6fce5ddf3e6b4c3 /openpgp/src/parse
parentec1063a3c684b5c44886907b2a9817ff2e557be7 (diff)
openpgp: Use a Vec instead of a HashMap.
- A SignatureGroup currently contains a hash mapping hash algorithms to hash contexts. Typically this will only contain one or two mappings. At most it will contain one mapping for each algorithm that we support (currently, we support 7 hash algorithms). - Given the small expected and small maximum size, a vector is the better data structure: - The small number of elements means that look up time will be comparable whether we do a linear scan or look in a hash (in fact, the linear scan is probably cache friendlier). - Iterating over a vector is faster than iterating over a hash map. The is the fast path. - A vector takes up less space. - Change SignatureGroup::hashes to use a Vec instead of a HashMap.
Diffstat (limited to 'openpgp/src/parse')
-rw-r--r--openpgp/src/parse/hashed_reader.rs3
-rw-r--r--openpgp/src/parse/parse.rs27
2 files changed, 20 insertions, 10 deletions
diff --git a/openpgp/src/parse/hashed_reader.rs b/openpgp/src/parse/hashed_reader.rs
index ff1f77da..120cf222 100644
--- a/openpgp/src/parse/hashed_reader.rs
+++ b/openpgp/src/parse/hashed_reader.rs
@@ -39,7 +39,8 @@ impl<R: BufferedReader<Cookie>> HashedReader<R> {
-> Self {
let mut cookie = Cookie::default();
for &algo in &algos {
- cookie.sig_group_mut().hashes.insert(algo, algo.context().unwrap());
+ cookie.sig_group_mut().hashes
+ .push((algo, algo.context().unwrap()));
}
cookie.hashes_for = hashes_for;
diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs
index 8541e660..06920967 100644
--- a/openpgp/src/parse/parse.rs
+++ b/openpgp/src/parse/parse.rs
@@ -2,7 +2,6 @@ use std;
use std::io;
use std::io::prelude::*;
use std::cmp;
-use std::collections::HashMap;
use std::str;
use std::mem;
use std::fmt;
@@ -489,12 +488,12 @@ pub(crate) struct SignatureGroup {
ops_count: usize,
/// Maps hash algorithms to hash contexts.
- pub(crate) hashes: HashMap<HashAlgorithm, crypto::hash::Context>,
+ pub(crate) hashes: Vec<(HashAlgorithm, crypto::hash::Context)>,
}
impl fmt::Debug for SignatureGroup {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let algos = self.hashes.keys()
+ let algos = self.hashes.iter().map(|(a, _)| a)
.collect::<Vec<&HashAlgorithm>>();
f.debug_struct("Cookie")
@@ -508,7 +507,7 @@ impl Default for SignatureGroup {
fn default() -> Self {
SignatureGroup {
ops_count: 0,
- hashes: HashMap::new(),
+ hashes: Default::default(),
}
}
}
@@ -1051,7 +1050,12 @@ impl Signature4 {
if cookie.hashes_for == HashesFor::Signature {
cookie.sig_group_mut().ops_count -= 1;
if let Some(hash) =
- cookie.sig_group().hashes.get(&hash_algo)
+ cookie.sig_group().hashes.iter().find_map(
+ |(a, h)| if *a == hash_algo {
+ Some(h)
+ } else {
+ None
+ })
{
t!("popped a {:?} HashedReader", hash_algo);
computed_hash = Some((cookie.signature_level(),
@@ -1224,11 +1228,11 @@ impl OnePassSig3 {
// Make sure that it uses the required
// hash algorithm.
if ! cookie.sig_group()
- .hashes.contains_key(&hash_algo)
+ .hashes.iter().any(|(a, _)| *a == hash_algo)
{
if let Ok(ctx) = hash_algo.context() {
cookie.sig_group_mut()
- .hashes.insert(hash_algo, ctx);
+ .hashes.push((hash_algo, ctx));
}
}
@@ -2023,8 +2027,13 @@ impl MDC {
if state.hashes_for == HashesFor::MDC {
if state.sig_group().hashes.len() > 0 {
let h = state.sig_group_mut().hashes
- .get_mut(&HashAlgorithm::SHA1)
- .unwrap();
+ .iter_mut().find_map(
+ |(a, h)|
+ if *a == HashAlgorithm::SHA1 {
+ Some(h)
+ } else {
+ None
+ }).unwrap();
h.digest(&mut computed_hash);
}