unistore-cache 0.1.0

In-memory cache capability for UniStore
Documentation
//! 【统计信息】- 缓存统计
//!
//! 职责:
//! - 跟踪缓存命中/未命中
//! - 提供性能指标

use std::sync::atomic::{AtomicU64, Ordering};

/// 缓存统计
#[derive(Debug, Default)]
pub struct CacheStats {
    /// 命中次数
    hits: AtomicU64,
    /// 未命中次数
    misses: AtomicU64,
    /// 插入次数
    inserts: AtomicU64,
    /// 淘汰次数
    evictions: AtomicU64,
    /// 过期删除次数
    expirations: AtomicU64,
}

impl CacheStats {
    /// 创建新的统计实例
    pub fn new() -> Self {
        Self::default()
    }

    /// 记录命中
    pub fn record_hit(&self) {
        self.hits.fetch_add(1, Ordering::Relaxed);
    }

    /// 记录未命中
    pub fn record_miss(&self) {
        self.misses.fetch_add(1, Ordering::Relaxed);
    }

    /// 记录插入
    pub fn record_insert(&self) {
        self.inserts.fetch_add(1, Ordering::Relaxed);
    }

    /// 记录淘汰
    pub fn record_eviction(&self) {
        self.evictions.fetch_add(1, Ordering::Relaxed);
    }

    /// 记录过期
    pub fn record_expiration(&self) {
        self.expirations.fetch_add(1, Ordering::Relaxed);
    }

    /// 获取命中次数
    pub fn hits(&self) -> u64 {
        self.hits.load(Ordering::Relaxed)
    }

    /// 获取未命中次数
    pub fn misses(&self) -> u64 {
        self.misses.load(Ordering::Relaxed)
    }

    /// 获取插入次数
    pub fn inserts(&self) -> u64 {
        self.inserts.load(Ordering::Relaxed)
    }

    /// 获取淘汰次数
    pub fn evictions(&self) -> u64 {
        self.evictions.load(Ordering::Relaxed)
    }

    /// 获取过期删除次数
    pub fn expirations(&self) -> u64 {
        self.expirations.load(Ordering::Relaxed)
    }

    /// 计算命中率(0.0 - 1.0)
    pub fn hit_rate(&self) -> f64 {
        let hits = self.hits();
        let total = hits + self.misses();
        if total == 0 {
            0.0
        } else {
            hits as f64 / total as f64
        }
    }

    /// 获取总请求数
    pub fn total_requests(&self) -> u64 {
        self.hits() + self.misses()
    }

    /// 重置统计
    pub fn reset(&self) {
        self.hits.store(0, Ordering::Relaxed);
        self.misses.store(0, Ordering::Relaxed);
        self.inserts.store(0, Ordering::Relaxed);
        self.evictions.store(0, Ordering::Relaxed);
        self.expirations.store(0, Ordering::Relaxed);
    }

    /// 创建快照
    pub fn snapshot(&self) -> CacheStatsSnapshot {
        CacheStatsSnapshot {
            hits: self.hits(),
            misses: self.misses(),
            inserts: self.inserts(),
            evictions: self.evictions(),
            expirations: self.expirations(),
        }
    }
}

/// 统计快照(不可变)
#[derive(Debug, Clone)]
pub struct CacheStatsSnapshot {
    /// 命中次数
    pub hits: u64,
    /// 未命中次数
    pub misses: u64,
    /// 插入次数
    pub inserts: u64,
    /// 淘汰次数
    pub evictions: u64,
    /// 过期删除次数
    pub expirations: u64,
}

impl CacheStatsSnapshot {
    /// 计算命中率
    pub fn hit_rate(&self) -> f64 {
        let total = self.hits + self.misses;
        if total == 0 {
            0.0
        } else {
            self.hits as f64 / total as f64
        }
    }

    /// 获取总请求数
    pub fn total_requests(&self) -> u64 {
        self.hits + self.misses
    }
}

impl std::fmt::Display for CacheStatsSnapshot {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "CacheStats {{ hits: {}, misses: {}, hit_rate: {:.2}%, inserts: {}, evictions: {}, expirations: {} }}",
            self.hits,
            self.misses,
            self.hit_rate() * 100.0,
            self.inserts,
            self.evictions,
            self.expirations
        )
    }
}