// todo: split between inner and dynamic shard stats.

#[derive(Debug, Default, Clone)]
pub struct ShardStats {
    pub executions_complete: u64,
    pub executions_pending: usize,
    pub keys_lru_evicted: u64,
    pub keys_ttl_evicted: u64,
    pub keys_taken: u64,
    pub loads_in_progress: usize,
    pub loads_failed: u64,
    pub loads_not_found: u64,
    pub loads_complete: u64,
    pub data_size: usize,
    pub expiring_keys: usize,
}

impl ShardStats {
    pub fn merge_stats<S: IntoIterator<Item = ShardStats>>(stats: S) -> Self {
        stats
            .into_iter()
            .fold(ShardStats::default(), |s, d| s.merge(d))
    }

    fn merge(self, other: ShardStats) -> Self {
        Self {
            executions_complete: self.executions_complete + other.executions_complete,
            executions_pending: self.executions_pending + other.executions_pending,
            loads_in_progress: self.loads_in_progress + other.loads_in_progress,
            data_size: self.data_size + other.data_size,
            keys_lru_evicted: self.keys_lru_evicted + other.keys_lru_evicted,
            keys_ttl_evicted: self.keys_ttl_evicted + other.keys_ttl_evicted,
            keys_taken: self.keys_taken + other.keys_taken,
            expiring_keys: self.expiring_keys + other.expiring_keys,
            loads_failed: self.loads_failed + other.loads_failed,
            loads_not_found: self.loads_not_found + other.loads_not_found,
            loads_complete: self.loads_complete + other.loads_complete,
        }
    }
}
