use std::collections::HashMap;
use nodedb_types::Hlc;
use tracing::{debug, warn};
use crate::metadata_group::descriptors::{DescriptorId, DescriptorLease};
use crate::metadata_group::entry::{MetadataEntry, RoutingChange, TopologyChange};
#[derive(Debug, Default)]
pub struct MetadataCache {
pub applied_index: u64,
pub last_applied_hlc: Hlc,
pub leases: HashMap<(DescriptorId, u64), DescriptorLease>,
pub topology_log: Vec<TopologyChange>,
pub routing_log: Vec<RoutingChange>,
pub cluster_version: u16,
pub catalog_entries_applied: u64,
}
impl MetadataCache {
pub fn new() -> Self {
Self::default()
}
pub fn apply(&mut self, index: u64, entry: &MetadataEntry) {
if index != 0 && index <= self.applied_index {
debug!(
index,
watermark = self.applied_index,
"metadata cache: skipping already-applied entry"
);
return;
}
self.applied_index = index;
match entry {
MetadataEntry::CatalogDdl { payload: _ }
| MetadataEntry::CatalogDdlAudited { payload: _, .. } => {
self.catalog_entries_applied += 1;
}
MetadataEntry::TopologyChange(change) => self.topology_log.push(change.clone()),
MetadataEntry::RoutingChange(change) => self.routing_log.push(change.clone()),
MetadataEntry::ClusterVersionBump { from, to } => {
if *from != self.cluster_version && self.cluster_version != 0 {
warn!(
expected = self.cluster_version,
got = *from,
"cluster version bump mismatch"
);
}
self.cluster_version = *to;
}
MetadataEntry::DescriptorLeaseGrant(lease) => {
if lease.expires_at > self.last_applied_hlc {
self.last_applied_hlc = lease.expires_at;
}
self.leases
.insert((lease.descriptor_id.clone(), lease.node_id), lease.clone());
}
MetadataEntry::DescriptorLeaseRelease {
node_id,
descriptor_ids,
} => {
for id in descriptor_ids {
self.leases.remove(&(id.clone(), *node_id));
}
}
MetadataEntry::DescriptorDrainStart { expires_at, .. } => {
if *expires_at > self.last_applied_hlc {
self.last_applied_hlc = *expires_at;
}
}
MetadataEntry::DescriptorDrainEnd { .. } => {}
MetadataEntry::CaTrustChange { .. } => {
}
MetadataEntry::Batch { entries } => {
for sub in entries {
self.apply(index, sub);
}
}
}
}
}