use chrono;
use serde::{Deserialize, Serialize};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheValue {
pub data: Vec<u8>,
pub created_at: u64,
pub last_accessed: u64,
pub expires_at: Option<u64>,
pub access_count: u64,
pub is_compressed: bool,
pub original_size: usize,
pub compressed_size: usize,
}
impl CacheValue {
pub fn new(data: Vec<u8>, compressed: bool, original_size: usize) -> Self {
let size = data.len();
Self {
data,
created_at: current_timestamp(),
last_accessed: current_timestamp(),
expires_at: None,
access_count: 1,
is_compressed: compressed,
original_size,
compressed_size: size,
}
}
pub fn new_uncompressed(data: Vec<u8>) -> Self {
let size = data.len();
Self::new(data, false, size)
}
pub fn new_compressed(
compressed_data: Vec<u8>,
original_size: usize,
) -> Self {
Self::new(compressed_data, true, original_size)
}
pub fn is_expired(&self) -> bool {
if let Some(expires_at) = self.expires_at {
current_timestamp() > expires_at
} else {
false
}
}
pub fn touch(&mut self) {
self.last_accessed = current_timestamp();
self.access_count += 1;
}
pub fn remaining_ttl(&self) -> Option<u64> {
self.expires_at.map(|expires_at| {
let now = current_timestamp();
if expires_at > now {
expires_at - now
} else {
0
}
})
}
pub fn age(&self) -> u64 {
current_timestamp() - self.created_at
}
pub fn idle_time(&self) -> u64 {
current_timestamp() - self.last_accessed
}
pub fn compression_ratio(&self) -> f64 {
if self.original_size == 0 {
1.0
} else {
self.compressed_size as f64 / self.original_size as f64
}
}
pub fn size(&self) -> usize {
self.data.len()
}
pub fn memory_size(&self) -> usize {
self.data.len() + std::mem::size_of::<Self>()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EvictionStrategy {
Lru,
Lfu,
Fifo,
LruLfu,
TtlBased,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CacheLayer {
Memory,
Persistent,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CacheOperation {
Get,
Set,
Delete,
Clear,
Expire,
}
pub fn current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
}
pub fn duration_to_seconds(duration: Duration) -> u64 {
duration.as_secs()
}
pub fn seconds_to_duration(seconds: u64) -> Duration {
Duration::from_secs(seconds)
}