use rat_memcache::RatMemCacheBuilder;
use rat_memcache::config::{L1Config, PerformanceConfig, TtlConfig, LoggingConfig};
use bytes::Bytes;
use tempfile::TempDir;
#[cfg(feature = "melange-storage")]
use rat_memcache::config::{L2Config, CacheWarmupStrategy};
#[cfg(feature = "melange-storage")]
use rat_memcache::CompressionAlgorithm;
#[cfg(feature = "melange-storage")]
#[tokio::test]
async fn test_compression_architecture() {
let temp_dir = TempDir::new().unwrap();
let compression_threshold = 128; let compression_max_threshold = 1024 * 1024; let large_value_threshold = 10240;
let cache = RatMemCacheBuilder::new()
.l1_config(L1Config {
max_memory: 1024 * 1024 * 1024, max_entries: 100000,
eviction_strategy: rat_memcache::EvictionStrategy::Lru,
})
.l2_config(L2Config {
enable_l2_cache: true,
data_dir: Some(temp_dir.path().to_path_buf()),
max_disk_size: 1024 * 1024 * 1024, write_buffer_size: 64 * 1024 * 1024, max_write_buffer_number: 3,
block_cache_size: 32 * 1024 * 1024, background_threads: 4,
clear_on_startup: false,
enable_lz4: true,
compression_threshold,
compression_max_threshold,
compression_level: 6,
cache_size_mb: 512,
max_file_size_mb: 1024,
smart_flush_enabled: true,
smart_flush_base_interval_ms: 100,
smart_flush_min_interval_ms: 20,
smart_flush_max_interval_ms: 500,
smart_flush_write_rate_threshold: 8000,
smart_flush_accumulated_bytes_threshold: 8388608,
cache_warmup_strategy: CacheWarmupStrategy::Recent,
zstd_compression_level: None,
l2_write_strategy: "write_through".to_string(),
l2_write_threshold: 1024,
l2_write_ttl_threshold: 300,
})
.performance_config(PerformanceConfig {
worker_threads: 4,
enable_concurrency: true,
read_write_separation: true,
batch_size: 100,
enable_warmup: true,
large_value_threshold,
})
.ttl_config(TtlConfig {
expire_seconds: Some(3600),
cleanup_interval: 300,
max_cleanup_entries: 1000,
lazy_expiration: true,
active_expiration: true,
})
.logging_config(LoggingConfig {
level: "DEBUG".to_string(),
enable_colors: true,
show_timestamp: true,
enable_performance_logs: true,
enable_audit_logs: true,
enable_cache_logs: true,
enable_logging: true,
enable_async: false,
batch_size: 2048,
batch_interval_ms: 25,
buffer_size: 16384,
})
.build()
.await
.expect("Failed to create cache");
let small_value = Bytes::from(vec![b'x'; 100]); println!("=== 测试1: 小值处理({}字节)===", small_value.len());
cache.set("small_key".to_string(), small_value.clone()).await
.expect("Failed to set small value");
let retrieved_small = cache.get("small_key").await
.expect("Failed to get small value")
.expect("Small value not found");
assert_eq!(retrieved_small, small_value);
println!("✓ 小值处理正确");
let medium_value = Bytes::from(vec![b'y'; 20480]); println!("\n=== 测试2: 中等值处理({}字节)===", medium_value.len());
cache.set("medium_key".to_string(), medium_value.clone()).await
.expect("Failed to set medium value");
let retrieved_medium = cache.get("medium_key").await
.expect("Failed to get medium value")
.expect("Medium value not found");
assert_eq!(retrieved_medium, medium_value);
println!("✓ 中等值处理正确");
let compressible_value = Bytes::from(vec![b'z'; 204800]); println!("\n=== 测试3: 压缩范围内值处理({}字节)===", compressible_value.len());
cache.set("compressible_key".to_string(), compressible_value.clone()).await
.expect("Failed to set compressible value");
let retrieved_compressible = cache.get("compressible_key").await
.expect("Failed to get compressible value")
.expect("Compressible value not found");
assert_eq!(retrieved_compressible, compressible_value);
println!("✓ 压缩范围内值处理正确");
let huge_value = Bytes::from(vec![b'w'; 2 * 1024 * 1024]); println!("\n=== 测试4: 超过压缩最大阈值值处理({}字节)===", huge_value.len());
cache.set("huge_key".to_string(), huge_value.clone()).await
.expect("Failed to set huge value");
let retrieved_huge = cache.get("huge_key").await
.expect("Failed to get huge value")
.expect("Huge value not found");
assert_eq!(retrieved_huge, huge_value);
println!("✓ 超过压缩最大阈值值处理正确");
let l1_stats = cache.get_l1_stats().await;
let l2_stats = cache.get_l2_stats().await;
println!("\n=== 统计信息 ===");
println!("L1缓存条目数: {}", l1_stats.entry_count);
println!("L2缓存写入次数: {}", l2_stats.writes);
assert!(l1_stats.entry_count > 0, "L1缓存应该有数据");
assert!(l2_stats.writes > 0, "L2缓存应该有写入操作");
println!("\n=== 架构验证总结 ===");
println!("✓ 小值(<10KB) -> L1缓存 -> 不压缩");
println!("✓ 中等值(≥10KB) -> L2缓存 -> 小于压缩阈值(128字节) -> 不压缩");
println!("✓ 大值(128字节~1MB) -> L2缓存 -> 在压缩范围内 -> 压缩");
println!("✓ 超大值(>1MB) -> L2缓存 -> 超过压缩最大阈值 -> 不压缩");
println!("✓ 压缩判断逻辑已正确下沉到L2层!");
}
#[cfg(feature = "melange-storage")]
#[tokio::test]
async fn test_compression_disabled() {
let temp_dir = TempDir::new().unwrap();
let cache = RatMemCacheBuilder::new()
.l1_config(L1Config {
max_memory: 1024 * 1024 * 1024,
max_entries: 100000,
eviction_strategy: rat_memcache::EvictionStrategy::Lru,
})
.l2_config(L2Config {
enable_l2_cache: true,
data_dir: Some(temp_dir.path().to_path_buf()),
max_disk_size: 1024 * 1024 * 1024,
write_buffer_size: 64 * 1024 * 1024,
max_write_buffer_number: 3,
block_cache_size: 32 * 1024 * 1024,
background_threads: 4,
clear_on_startup: false,
enable_lz4: false, compression_threshold: 128,
compression_max_threshold: 1024 * 1024,
compression_level: 6,
cache_size_mb: 512,
max_file_size_mb: 1024,
smart_flush_enabled: true,
smart_flush_base_interval_ms: 100,
smart_flush_min_interval_ms: 20,
smart_flush_max_interval_ms: 500,
smart_flush_write_rate_threshold: 8000,
smart_flush_accumulated_bytes_threshold: 8388608,
cache_warmup_strategy: CacheWarmupStrategy::Recent,
zstd_compression_level: None,
l2_write_strategy: "write_through".to_string(),
l2_write_threshold: 1024,
l2_write_ttl_threshold: 300,
})
.performance_config(PerformanceConfig {
worker_threads: 4,
enable_concurrency: true,
read_write_separation: true,
batch_size: 100,
enable_warmup: true,
large_value_threshold: 10240,
})
.ttl_config(TtlConfig {
expire_seconds: None,
cleanup_interval: 60,
max_cleanup_entries: 100,
lazy_expiration: true,
active_expiration: true,
})
.logging_config(LoggingConfig {
level: "debug".to_string(),
enable_colors: false,
show_timestamp: false,
enable_performance_logs: true,
enable_audit_logs: false,
enable_cache_logs: true,
enable_logging: true,
enable_async: false,
batch_size: 2048,
batch_interval_ms: 25,
buffer_size: 16384,
})
.build()
.await
.expect("Failed to create cache");
let value = Bytes::from(vec![b'x'; 204800]); cache.set("test_key".to_string(), value.clone()).await
.expect("Failed to set value");
let retrieved = cache.get("test_key").await
.expect("Failed to get value")
.expect("Value not found");
assert_eq!(retrieved, value);
println!("✓ 压缩禁用时处理正确");
}