1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
use std::collections::hash_map::Entry;
use massa_models::{
address::Address,
endorsement::{EndorsementId, SecureShareEndorsement},
prehash::{PreHashMap, PreHashSet},
};
/// Container for all endorsements and different indexes.
/// Note: The structure can evolve and store more indexes.
#[derive(Default)]
pub struct EndorsementIndexes {
/// Endorsements structure container
endorsements: PreHashMap<EndorsementId, Box<SecureShareEndorsement>>,
/// Structure mapping creators with the created endorsements
index_by_creator: PreHashMap<Address, PreHashSet<EndorsementId>>,
}
impl EndorsementIndexes {
/// Insert an endorsement and populate the indexes.
/// Arguments:
/// - endorsement: the endorsement to insert
pub(crate) fn insert(&mut self, endorsement: SecureShareEndorsement) {
if let Entry::Vacant(vac) = self.endorsements.entry(endorsement.id) {
let endorsement = vac.insert(Box::new(endorsement));
// update creator index
self.index_by_creator
.entry(endorsement.content_creator_address)
.or_default()
.insert(endorsement.id);
massa_metrics::set_endorsements_counter(self.endorsements.len());
}
}
/// Remove a endorsement, remove from the indexes and made some clean-up in indexes if necessary.
/// Arguments:
/// * `endorsement_id`: the endorsement id to remove
pub(crate) fn remove(
&mut self,
endorsement_id: &EndorsementId,
) -> Option<Box<SecureShareEndorsement>> {
if let Some(e) = self.endorsements.remove(endorsement_id) {
massa_metrics::set_endorsements_counter(self.endorsements.len());
// update creator index
if let Entry::Occupied(mut occ) = self.index_by_creator.entry(e.content_creator_address)
{
occ.get_mut().remove(&e.id);
if occ.get().is_empty() {
occ.remove();
}
}
return Some(e);
}
None
}
/// Gets a reference to a stored endorsement, if any.
pub fn get(&self, id: &EndorsementId) -> Option<&SecureShareEndorsement> {
self.endorsements.get(id).map(|v| v.as_ref())
}
/// Checks whether an endorsement exists in global storage.
pub fn contains(&self, id: &EndorsementId) -> bool {
self.endorsements.contains_key(id)
}
/// Get endorsements created by an address
/// Arguments:
/// - address: the address to get the endorsements created by
///
/// Returns:
/// - optional reference to a set of endorsements created by that address
pub fn get_endorsements_created_by(
&self,
address: &Address,
) -> Option<&PreHashSet<EndorsementId>> {
self.index_by_creator.get(address)
}
}