remove hashmap from stake_history (#5834)
This commit is contained in:
parent
bdda79343e
commit
affcb5ec43
|
@ -20,10 +20,7 @@ crate::solana_name_id!(ID, "SysvarS1otHashes111111111111111111111111111");
|
|||
pub const MAX_SLOT_HASHES: usize = 512; // 512 slots to get your vote in
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
pub struct SlotHashes {
|
||||
// non-pub to keep control of size
|
||||
inner: Vec<(Slot, Hash)>,
|
||||
}
|
||||
pub struct SlotHashes(Vec<(Slot, Hash)>);
|
||||
|
||||
impl SlotHashes {
|
||||
pub fn from(account: &Account) -> Option<Self> {
|
||||
|
@ -34,26 +31,30 @@ impl SlotHashes {
|
|||
}
|
||||
|
||||
pub fn size_of() -> usize {
|
||||
serialized_size(&SlotHashes {
|
||||
inner: vec![(0, Hash::default()); MAX_SLOT_HASHES],
|
||||
})
|
||||
.unwrap() as usize
|
||||
serialized_size(&SlotHashes(vec![(0, Hash::default()); MAX_SLOT_HASHES])).unwrap() as usize
|
||||
}
|
||||
pub fn add(&mut self, slot: Slot, hash: Hash) {
|
||||
self.inner.insert(0, (slot, hash));
|
||||
self.inner.truncate(MAX_SLOT_HASHES);
|
||||
match self.binary_search_by(|probe| slot.cmp(&probe.0)) {
|
||||
Ok(index) => (self.0)[index] = (slot, hash),
|
||||
Err(index) => (self.0).insert(index, (slot, hash)),
|
||||
}
|
||||
(self.0).truncate(MAX_SLOT_HASHES);
|
||||
}
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
pub fn get(&self, slot: &Slot) -> Option<&Hash> {
|
||||
self.binary_search_by(|probe| slot.cmp(&probe.0))
|
||||
.ok()
|
||||
.map(|index| &self[index].1)
|
||||
}
|
||||
pub fn new(slot_hashes: &[(Slot, Hash)]) -> Self {
|
||||
Self {
|
||||
inner: slot_hashes.to_vec(),
|
||||
}
|
||||
Self(slot_hashes.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SlotHashes {
|
||||
type Target = Vec<(u64, Hash)>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ mod tests {
|
|||
let account = create_account(lamports, &[]);
|
||||
assert_eq!(account.data.len(), SlotHashes::size_of());
|
||||
let slot_hashes = SlotHashes::from(&account);
|
||||
assert_eq!(slot_hashes, Some(SlotHashes { inner: vec![] }));
|
||||
assert_eq!(slot_hashes, Some(SlotHashes(vec![])));
|
||||
let mut slot_hashes = slot_hashes.unwrap();
|
||||
for i in 0..MAX_SLOT_HASHES + 1 {
|
||||
slot_hashes.add(
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
//!
|
||||
//! this account carries history about stake activations and de-activations
|
||||
//!
|
||||
use crate::account::Account;
|
||||
use crate::sysvar;
|
||||
use bincode::serialized_size;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
|
||||
pub use crate::clock::Epoch;
|
||||
use crate::{account::Account, sysvar};
|
||||
use bincode::serialized_size;
|
||||
use std::ops::Deref;
|
||||
|
||||
const ID: [u8; 32] = [
|
||||
6, 167, 213, 23, 25, 53, 132, 208, 254, 237, 155, 179, 67, 29, 19, 32, 107, 229, 68, 40, 27,
|
||||
|
@ -27,9 +24,7 @@ pub struct StakeHistoryEntry {
|
|||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
|
||||
pub struct StakeHistory {
|
||||
inner: HashMap<Epoch, StakeHistoryEntry>,
|
||||
}
|
||||
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);
|
||||
|
||||
impl StakeHistory {
|
||||
pub fn from(account: &Account) -> Option<Self> {
|
||||
|
@ -40,27 +35,33 @@ impl StakeHistory {
|
|||
}
|
||||
|
||||
pub fn size_of() -> usize {
|
||||
serialized_size(
|
||||
&(0..MAX_STAKE_HISTORY)
|
||||
.map(|i| (i as u64, StakeHistoryEntry::default()))
|
||||
.collect::<HashMap<_, _>>(),
|
||||
)
|
||||
serialized_size(&StakeHistory(vec![
|
||||
(0, StakeHistoryEntry::default());
|
||||
MAX_STAKE_HISTORY
|
||||
]))
|
||||
.unwrap() as usize
|
||||
}
|
||||
pub fn add(&mut self, epoch: Epoch, entry: StakeHistoryEntry) {
|
||||
self.inner.insert(epoch, entry);
|
||||
|
||||
if self.len() > MAX_STAKE_HISTORY {
|
||||
let oldest = *self.inner.keys().min().unwrap();
|
||||
self.inner.remove(&oldest);
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
pub fn get(&self, epoch: &Epoch) -> Option<&StakeHistoryEntry> {
|
||||
self.binary_search_by(|probe| epoch.cmp(&probe.0))
|
||||
.ok()
|
||||
.map(|index| &self[index].1)
|
||||
}
|
||||
|
||||
pub fn add(&mut self, epoch: Epoch, entry: StakeHistoryEntry) {
|
||||
match self.binary_search_by(|probe| epoch.cmp(&probe.0)) {
|
||||
Ok(index) => (self.0)[index] = (epoch, entry),
|
||||
Err(index) => (self.0).insert(index, (epoch, entry)),
|
||||
}
|
||||
(self.0).truncate(MAX_STAKE_HISTORY);
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for StakeHistory {
|
||||
type Target = HashMap<Epoch, StakeHistoryEntry>;
|
||||
type Target = Vec<(Epoch, StakeHistoryEntry)>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,15 @@ mod tests {
|
|||
);
|
||||
}
|
||||
assert_eq!(stake_history.len(), MAX_STAKE_HISTORY);
|
||||
assert_eq!(*stake_history.keys().min().unwrap(), 1);
|
||||
assert_eq!(stake_history.iter().map(|entry| entry.0).min().unwrap(), 1);
|
||||
assert_eq!(stake_history.get(&0), None);
|
||||
assert_eq!(
|
||||
stake_history.get(&1),
|
||||
Some(&StakeHistoryEntry {
|
||||
activating: 1,
|
||||
..StakeHistoryEntry::default()
|
||||
})
|
||||
);
|
||||
// verify the account can hold a full instance
|
||||
assert_eq!(
|
||||
StakeHistory::from(&create_account(lamports, &stake_history)),
|
||||
|
|
Loading…
Reference in New Issue