Fast CompactAssignment search (#8385)

* use more efficient search through candidates in offchain-election

* mark linear accessors as test-only in election-provider-multi-phase

This prevents production code which uses them from compiling.

Also write an efficient helper for getting the target index.

* doc grammar

* use faster target_index_fn in benchmarks

* unbox helper functions

* remove unnecessary import

* write lifetime after primary trait

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Peter Goodspeed-Niklaus
2021-03-18 09:38:58 +01:00
committed by GitHub
parent 15e15e7d8e
commit 05f24931a9
4 changed files with 67 additions and 37 deletions
@@ -31,7 +31,7 @@ use sp_npos_elections::{
use sp_runtime::{
offchain::storage::StorageValueRef, traits::TrailingZeroInput, RuntimeDebug,
};
use sp_std::{convert::TryInto, prelude::*};
use sp_std::{convert::TryInto, prelude::*, collections::btree_map::BTreeMap};
/// Error types related to the offchain election machinery.
#[derive(RuntimeDebug)]
@@ -331,18 +331,22 @@ pub fn prepare_submission<T: Config>(
let snapshot_nominators =
<Module<T>>::snapshot_nominators().ok_or(OffchainElectionError::SnapshotUnavailable)?;
// indexing caches
let nominator_indices: BTreeMap<_, _> =
snapshot_nominators.iter().enumerate().map(|(idx, account_id)| (account_id, idx)).collect();
let validator_indices: BTreeMap<_, _> =
snapshot_validators.iter().enumerate().map(|(idx, account_id)| (account_id, idx)).collect();
// all helper closures that we'd ever need.
let nominator_index = |a: &T::AccountId| -> Option<NominatorIndex> {
snapshot_nominators
.iter()
.position(|x| x == a)
.and_then(|i| <usize as TryInto<NominatorIndex>>::try_into(i).ok())
nominator_indices
.get(a)
.and_then(|i| <usize as TryInto<NominatorIndex>>::try_into(*i).ok())
};
let validator_index = |a: &T::AccountId| -> Option<ValidatorIndex> {
snapshot_validators
.iter()
.position(|x| x == a)
.and_then(|i| <usize as TryInto<ValidatorIndex>>::try_into(i).ok())
validator_indices
.get(a)
.and_then(|i| <usize as TryInto<ValidatorIndex>>::try_into(*i).ok())
};
let nominator_at = |i: NominatorIndex| -> Option<T::AccountId> {
snapshot_nominators.get(i as usize).cloned()