Skip to content

Commit

Permalink
Small optimization in check_no_missing_bytecode (#2038)
Browse files Browse the repository at this point in the history
## Motivation

We're currently creating the `required_hashes` `HashSet` just to check if we have any unneeded values

## Proposal

If we upgrade it to a `HashMap`, we can reuse it later and avoid having to create the `value_hashes` `HashSet` also, which optimizes things a bit

## Test Plan

CI
  • Loading branch information
Andre da Silva authored May 16, 2024
1 parent b1935fe commit 8212607
Showing 1 changed file with 13 additions and 20 deletions.
33 changes: 13 additions & 20 deletions linera-core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::{
borrow::Cow,
collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet, VecDeque},
collections::{hash_map, BTreeMap, BTreeSet, HashMap, VecDeque},
num::NonZeroUsize,
sync::Arc,
time::Duration,
Expand Down Expand Up @@ -741,49 +741,42 @@ where
block: &Block,
hashed_certificate_values: &[HashedCertificateValue],
) -> Result<(), WorkerError> {
let required_locations = block.bytecode_locations();
// Find all certificates containing bytecode used when executing this block.
let mut required_hashes: HashSet<_> = required_locations
.keys()
.map(|bytecode_location| bytecode_location.certificate_hash)
let mut required_locations_left: HashMap<_, _> = block
.bytecode_locations()
.into_keys()
.map(|bytecode_location| (bytecode_location.certificate_hash, bytecode_location))
.collect();
for value in hashed_certificate_values {
let value_hash = value.hash();
ensure!(
required_hashes.remove(&value_hash),
required_locations_left.remove(&value_hash).is_some(),
WorkerError::UnneededValue { value_hash }
);
}
let value_hashes: HashSet<_> = hashed_certificate_values
.iter()
.map(|hashed_certificate_value| hashed_certificate_value.hash())
.collect();
let recent_values = self.recent_values.lock().await;
let tasks = required_locations
.into_keys()
.filter(|location| {
!recent_values.contains(&location.certificate_hash)
&& !value_hashes.contains(&location.certificate_hash)
})
let tasks = required_locations_left
.into_values()
.filter(|location| !recent_values.contains(&location.certificate_hash))
.map(|location| {
self.storage
.contains_hashed_certificate_value(location.certificate_hash)
.map(move |result| (location, result))
})
.collect::<Vec<_>>();
let mut locations = vec![];
let mut missing_locations = vec![];
for (location, result) in future::join_all(tasks).await {
match result {
Ok(true) => {}
Ok(false) => locations.push(location),
Ok(false) => missing_locations.push(location),
Err(err) => Err(err)?,
}
}
if locations.is_empty() {
if missing_locations.is_empty() {
Ok(())
} else {
Err(WorkerError::ApplicationBytecodesNotFound(
locations.into_iter().collect(),
missing_locations.into_iter().collect(),
))
}
}
Expand Down

0 comments on commit 8212607

Please sign in to comment.