gemachain_program/
slot_hashes.rs1use crate::hash::Hash;
6use std::{iter::FromIterator, ops::Deref};
7
8pub const MAX_ENTRIES: usize = 512; pub use crate::clock::Slot;
11
12pub type SlotHash = (Slot, Hash);
13
14#[repr(C)]
15#[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
16pub struct SlotHashes(Vec<SlotHash>);
17
18impl SlotHashes {
19 pub fn add(&mut self, slot: Slot, hash: Hash) {
20 match self.binary_search_by(|(probe, _)| slot.cmp(probe)) {
21 Ok(index) => (self.0)[index] = (slot, hash),
22 Err(index) => (self.0).insert(index, (slot, hash)),
23 }
24 (self.0).truncate(MAX_ENTRIES);
25 }
26 #[allow(clippy::trivially_copy_pass_by_ref)]
27 pub fn get(&self, slot: &Slot) -> Option<&Hash> {
28 self.binary_search_by(|(probe, _)| slot.cmp(probe))
29 .ok()
30 .map(|index| &self[index].1)
31 }
32 pub fn new(slot_hashes: &[SlotHash]) -> Self {
33 let mut slot_hashes = slot_hashes.to_vec();
34 slot_hashes.sort_by(|(a, _), (b, _)| b.cmp(a));
35 Self(slot_hashes)
36 }
37}
38
39impl FromIterator<(Slot, Hash)> for SlotHashes {
40 fn from_iter<I: IntoIterator<Item = (Slot, Hash)>>(iter: I) -> Self {
41 Self(iter.into_iter().collect())
42 }
43}
44
45impl Deref for SlotHashes {
46 type Target = Vec<SlotHash>;
47 fn deref(&self) -> &Self::Target {
48 &self.0
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::hash::hash;
56
57 #[test]
58 fn test() {
59 let mut slot_hashes = SlotHashes::new(&[(1, Hash::default()), (3, Hash::default())]);
60 slot_hashes.add(2, Hash::default());
61 assert_eq!(
62 slot_hashes,
63 SlotHashes(vec![
64 (3, Hash::default()),
65 (2, Hash::default()),
66 (1, Hash::default()),
67 ])
68 );
69
70 let mut slot_hashes = SlotHashes::new(&[]);
71 for i in 0..MAX_ENTRIES + 1 {
72 slot_hashes.add(
73 i as u64,
74 hash(&[(i >> 24) as u8, (i >> 16) as u8, (i >> 8) as u8, i as u8]),
75 );
76 }
77 for i in 0..MAX_ENTRIES {
78 assert_eq!(slot_hashes[i].0, (MAX_ENTRIES - i) as u64);
79 }
80
81 assert_eq!(slot_hashes.len(), MAX_ENTRIES);
82 }
83}