uses structural sharing for stake-delegations hash-map (#23585)

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:
https://github.com/solana-labs/solana/issues/23061#issuecomment-1063444072

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/
This commit is contained in:
behzad nouri
2022-03-16 12:58:05 +00:00
committed by GitHub
parent 584ac80b1e
commit 3252dc7203
10 changed files with 118 additions and 145 deletions

View File

@@ -21,6 +21,7 @@ thiserror = "1.0"
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
generic-array = { version = "0.14.5", default-features = false, features = ["serde", "more_lengths"] }
im = { version = "15.0.0", features = ["rayon", "serde"] }
memmap2 = "0.5.3"
[target.'cfg(not(target_arch = "bpf"))'.dev-dependencies]

View File

@@ -371,6 +371,21 @@ impl<
}
}
#[cfg(not(target_arch = "bpf"))]
impl<
T: Clone + std::cmp::Eq + std::hash::Hash + AbiExample,
S: Clone + AbiExample,
H: std::hash::BuildHasher + Default,
> AbiExample for im::HashMap<T, S, H>
{
fn example() -> Self {
info!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
let mut map = im::HashMap::default();
map.insert(T::example(), S::example());
map
}
}
impl<T: std::cmp::Ord + AbiExample, S: AbiExample> AbiExample for BTreeMap<T, S> {
fn example() -> Self {
info!("AbiExample for (BTreeMap<T, S>): {}", type_name::<Self>());