use crate::event::EventSourced;
use std::any::TypeId;
use std::hash::{Hash, Hasher};
pub(crate) fn projection_cache_key<T>(entity: &str) -> Vec<u8>
where
T: EventSourced + 'static,
{
let schema_v = T::schema_version();
let type_disc = {
let mut h = std::collections::hash_map::DefaultHasher::new();
TypeId::of::<T>().hash(&mut h);
h.finish()
};
let kinds_disc = relevant_kinds_hash::<T>();
let mut cache_key = Vec::with_capacity(entity.len() + 1 + 8 + 8 + 8);
cache_key.extend_from_slice(entity.as_bytes());
cache_key.push(0);
cache_key.extend_from_slice(&type_disc.to_le_bytes());
cache_key.extend_from_slice(&schema_v.to_le_bytes());
cache_key.extend_from_slice(&kinds_disc.to_le_bytes());
cache_key
}
fn relevant_kinds_hash<T>() -> u64
where
T: EventSourced + 'static,
{
let mut kinds: Vec<u16> = T::relevant_event_kinds()
.iter()
.map(|k| (u16::from(k.category()) << 12) | k.type_id())
.collect();
kinds.sort_unstable();
let mut h = std::collections::hash_map::DefaultHasher::new();
for k in &kinds {
k.hash(&mut h);
}
kinds.len().hash(&mut h);
h.finish()
}