Skip to content

Commit

Permalink
uses structural sharing for stake-delegations hash-map
Browse files Browse the repository at this point in the history
StakeDelegations is using Arc to implement copy-on-write semantics:
https://github.com/solana-labs/solana/blob/58c0db970/runtime/src/stake_delegations.rs#L14-L16

However a single delegation change will still clone the entire hash-map,
resulting in excessive memory use as observed in:
solana-labs#23061 (comment)

This commit instead uses immutable hash-map implementing structural
sharing:
> which means that if two data structures are mostly copies of each
> other, most of the memory they take up will be shared between them.
https://docs.rs/im/latest/im/
  • Loading branch information
behzadnouri committed Mar 10, 2022
1 parent 58c0db9 commit c058e2f
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 136 deletions.
45 changes: 45 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions programs/bpf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ crossbeam-channel = "0.5"
dir-diff = "0.3.2"
flate2 = "1.0.22"
fnv = "1.0.7"
im = { version = "15.0.0", features = ["rayon", "serde"] }
index_list = "0.2.7"
itertools = "0.10.3"
lazy_static = "1.4.0"
Expand Down
12 changes: 8 additions & 4 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2525,9 +2525,13 @@ impl Bank {
let invalid_stake_keys: DashMap<Pubkey, InvalidCacheEntryReason> = DashMap::new();
let invalid_vote_keys: DashMap<Pubkey, InvalidCacheEntryReason> = DashMap::new();

let stake_delegations: Vec<_> = stakes
.stake_delegations()
.iter()
.map(|(&pubkey, &delegation)| (pubkey, delegation))
.collect();
thread_pool.install(|| {
stakes
.stake_delegations()
stake_delegations
.par_iter()
.for_each(|(stake_pubkey, delegation)| {
let vote_pubkey = &delegation.voter_pubkey;
Expand Down Expand Up @@ -6712,10 +6716,10 @@ pub(crate) mod tests {
genesis_sysvar_and_builtin_program_lamports, GenesisConfigInfo,
ValidatorVoteKeypairs,
},
stake_delegations::StakeDelegations,
status_cache::MAX_CACHE_ENTRIES,
},
crossbeam_channel::{bounded, unbounded},
im::HashMap as ImHashMap,
solana_program_runtime::invoke_context::InvokeContext,
solana_sdk::{
account::Account,
Expand Down Expand Up @@ -6755,7 +6759,7 @@ pub(crate) mod tests {
};

impl Bank {
fn cloned_stake_delegations(&self) -> StakeDelegations {
fn cloned_stake_delegations(&self) -> ImHashMap<Pubkey, Delegation> {
self.stakes_cache.stakes().stake_delegations().clone()
}
}
Expand Down
1 change: 0 additions & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ pub mod snapshot_hash;
pub mod snapshot_package;
pub mod snapshot_utils;
pub mod sorted_storages;
pub mod stake_delegations;
pub mod stake_history;
pub mod stake_weighted_timestamp;
pub mod stakes;
Expand Down
128 changes: 0 additions & 128 deletions runtime/src/stake_delegations.rs

This file was deleted.

6 changes: 3 additions & 3 deletions runtime/src/stakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! node stakes
use {
crate::{
stake_delegations::StakeDelegations,
stake_history::StakeHistory,
vote_account::{VoteAccount, VoteAccounts, VoteAccountsHashMap},
},
Expand All @@ -28,6 +27,7 @@ use {
collections::HashMap,
sync::{Arc, RwLock, RwLockReadGuard},
},
im::HashMap as ImHashMap,
};

#[derive(Debug, Clone, PartialEq, ToPrimitive)]
Expand Down Expand Up @@ -151,7 +151,7 @@ pub struct Stakes {
vote_accounts: VoteAccounts,

/// stake_delegations
stake_delegations: StakeDelegations,
stake_delegations: ImHashMap<Pubkey, Delegation>,

/// unused
unused: u64,
Expand Down Expand Up @@ -337,7 +337,7 @@ impl Stakes {
&self.vote_accounts
}

pub fn stake_delegations(&self) -> &StakeDelegations {
pub fn stake_delegations(&self) -> &ImHashMap<Pubkey, Delegation> {
&self.stake_delegations
}

Expand Down

0 comments on commit c058e2f

Please sign in to comment.