use chie_core::content_aware_cache::{CacheContentMetrics, ContentAwareCache, ContentType};
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::hint::black_box;
fn create_metrics(
content_type: ContentType,
size: usize,
freq: u32,
priority: u8,
) -> CacheContentMetrics {
CacheContentMetrics {
content_type,
size_bytes: size,
access_frequency: freq,
priority,
}
}
fn create_data(size: usize) -> Vec<u8> {
vec![0u8; size]
}
fn bench_cache_creation(c: &mut Criterion) {
let mut group = c.benchmark_group("cache_creation");
for &size_mb in &[10, 100, 500, 1000] {
let size_bytes = size_mb * 1024 * 1024;
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}MB", size_mb)),
&size_bytes,
|b, &s| {
b.iter(|| {
let cache = ContentAwareCache::new(black_box(s));
black_box(cache);
});
},
);
}
group.finish();
}
fn bench_insert_by_content_type(c: &mut Criterion) {
let mut group = c.benchmark_group("cache_insert_by_content_type");
let content_types = vec![
("Metadata", ContentType::Metadata, 1024),
("ImageChunk", ContentType::ImageChunk, 100 * 1024),
("VideoChunk", ContentType::VideoChunk, 256 * 1024),
("AudioChunk", ContentType::AudioChunk, 64 * 1024),
("DocumentChunk", ContentType::DocumentChunk, 50 * 1024),
("Generic", ContentType::Generic, 128 * 1024),
];
for (name, content_type, size) in content_types {
group.bench_with_input(
BenchmarkId::from_parameter(name),
&(content_type, size),
|b, &(ct, sz)| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
let metrics = create_metrics(ct, sz, 10, 5);
let data = create_data(sz);
cache.insert(black_box("key1".to_string()), data, metrics);
black_box(cache);
});
},
);
}
group.finish();
}
fn bench_insert_by_size(c: &mut Criterion) {
let mut group = c.benchmark_group("cache_insert_by_size");
for &size_kb in &[1, 10, 100, 1000] {
let size_bytes = size_kb * 1024;
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}KB", size_kb)),
&size_bytes,
|b, &sz| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
let metrics = create_metrics(ContentType::VideoChunk, sz, 10, 5);
let data = create_data(sz);
cache.insert(black_box("key1".to_string()), data, metrics);
black_box(cache);
});
},
);
}
group.finish();
}
fn bench_bulk_insert(c: &mut Criterion) {
let mut group = c.benchmark_group("cache_bulk_insert");
for &count in &[10, 50, 100, 500] {
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_entries", count)),
&count,
|b, &n| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..n {
let content_type = match i % 6 {
0 => ContentType::Metadata,
1 => ContentType::ImageChunk,
2 => ContentType::VideoChunk,
3 => ContentType::AudioChunk,
4 => ContentType::DocumentChunk,
_ => ContentType::Generic,
};
let size = 10 * 1024; let metrics = create_metrics(content_type, size, 10, 5);
let data = create_data(size);
cache.insert(format!("key{}", i), data, metrics);
}
black_box(cache);
});
},
);
}
group.finish();
}
fn bench_get_hit(c: &mut Criterion) {
c.bench_function("cache_get_hit", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
let metrics = create_metrics(ContentType::VideoChunk, 256 * 1024, 10, 5);
let data = create_data(256 * 1024);
cache.insert("key1".to_string(), data, metrics);
let result = cache.get(black_box("key1"));
black_box(result);
});
});
}
fn bench_get_miss(c: &mut Criterion) {
c.bench_function("cache_get_miss", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
let metrics = create_metrics(ContentType::VideoChunk, 256 * 1024, 10, 5);
let data = create_data(256 * 1024);
cache.insert("key1".to_string(), data, metrics);
let result = cache.get(black_box("nonexistent"));
black_box(result);
});
});
}
fn bench_repeated_access(c: &mut Criterion) {
c.bench_function("cache_repeated_access", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..10 {
let metrics = create_metrics(ContentType::VideoChunk, 100 * 1024, 10, 5);
let data = create_data(100 * 1024);
cache.insert(format!("key{}", i), data, metrics);
}
for _ in 0..20 {
let _ = cache.get("key0");
let _ = cache.get("key5");
let _ = cache.get("key9");
let _ = cache.get("nonexistent");
}
let hit_rate = cache.hit_rate();
black_box(hit_rate);
});
});
}
fn bench_remove(c: &mut Criterion) {
c.bench_function("cache_remove", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
let metrics = create_metrics(ContentType::VideoChunk, 256 * 1024, 10, 5);
let data = create_data(256 * 1024);
cache.insert("key1".to_string(), data, metrics);
let result = cache.remove(black_box("key1"));
black_box(result);
});
});
}
fn bench_clear(c: &mut Criterion) {
c.bench_function("cache_clear", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..100 {
let metrics = create_metrics(ContentType::Generic, 10 * 1024, 10, 5);
let data = create_data(10 * 1024);
cache.insert(format!("key{}", i), data, metrics);
}
cache.clear();
black_box(cache);
});
});
}
fn bench_stats_queries(c: &mut Criterion) {
c.bench_function("cache_stats_queries", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..50 {
let content_type = match i % 3 {
0 => ContentType::Metadata,
1 => ContentType::VideoChunk,
_ => ContentType::ImageChunk,
};
let metrics = create_metrics(content_type, 50 * 1024, 10, 5);
let data = create_data(50 * 1024);
cache.insert(format!("key{}", i), data, metrics);
}
let entry_count = cache.entry_count();
let usage = cache.usage_percentage();
let metadata_size = cache.size_by_type(ContentType::Metadata);
let video_size = cache.size_by_type(ContentType::VideoChunk);
let stats = cache.stats();
black_box((entry_count, usage, metadata_size, video_size, stats));
});
});
}
fn bench_adjust_size_with_eviction(c: &mut Criterion) {
c.bench_function("cache_adjust_size_eviction", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..100 {
let metrics = create_metrics(ContentType::VideoChunk, 500 * 1024, 10, 5);
let data = create_data(500 * 1024);
cache.insert(format!("key{}", i), data, metrics);
}
cache.adjust_size(black_box(20 * 1024 * 1024));
black_box(cache);
});
});
}
fn bench_recommended_size(c: &mut Criterion) {
c.bench_function("cache_recommended_size", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..50 {
let content_type = match i % 4 {
0 => ContentType::Metadata,
1 => ContentType::ImageChunk,
2 => ContentType::VideoChunk,
_ => ContentType::DocumentChunk,
};
let metrics = create_metrics(content_type, 100 * 1024, i as u32, 5);
let data = create_data(100 * 1024);
cache.insert(format!("key{}", i), data, metrics);
}
for i in 0..25 {
let _ = cache.get(&format!("key{}", i));
}
let recommended = cache.recommended_size();
black_box(recommended);
});
});
}
fn bench_eviction_by_priority(c: &mut Criterion) {
c.bench_function("cache_eviction_by_priority", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(5 * 1024 * 1024);
for i in 0..10 {
let metrics = create_metrics(ContentType::Generic, 500 * 1024, 1, 1);
let data = create_data(500 * 1024);
cache.insert(format!("low{}", i), data, metrics);
}
for i in 0..10 {
let metrics = create_metrics(ContentType::Metadata, 500 * 1024, 100, 9);
let data = create_data(500 * 1024);
cache.insert(format!("high{}", i), data, metrics);
}
black_box(cache);
});
});
}
fn bench_realistic_video_streaming(c: &mut Criterion) {
c.bench_function("cache_realistic_video_streaming", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(50 * 1024 * 1024);
for i in 0..10 {
let metrics = create_metrics(ContentType::Metadata, 2 * 1024, 50, 9);
let data = create_data(2 * 1024);
cache.insert(format!("manifest:{}", i), data, metrics);
}
for i in 0..100 {
let metrics = create_metrics(ContentType::VideoChunk, 256 * 1024, 10, 5);
let data = create_data(256 * 1024);
cache.insert(format!("video:chunk:{}", i), data, metrics);
}
for i in 0..20 {
let metrics = create_metrics(ContentType::ImageChunk, 50 * 1024, 2, 3);
let data = create_data(50 * 1024);
cache.insert(format!("preview:{}", i), data, metrics);
}
for i in 80..100 {
let _ = cache.get(&format!("video:chunk:{}", i));
}
let stats = cache.stats();
let hit_rate = cache.hit_rate();
black_box((stats, hit_rate, cache));
});
});
}
fn bench_realistic_web_content(c: &mut Criterion) {
c.bench_function("cache_realistic_web_content", |b| {
b.iter(|| {
let mut cache = ContentAwareCache::new(100 * 1024 * 1024);
for i in 0..50 {
let metrics = create_metrics(ContentType::Metadata, 5 * 1024, 100, 10);
let data = create_data(5 * 1024);
cache.insert(format!("api:/users/{}", i), data, metrics);
}
for i in 0..100 {
let metrics = create_metrics(ContentType::DocumentChunk, 30 * 1024, 20, 7);
let data = create_data(30 * 1024);
cache.insert(format!("page:/article/{}", i), data, metrics);
}
for i in 0..200 {
let metrics = create_metrics(ContentType::ImageChunk, 100 * 1024, 5, 4);
let data = create_data(100 * 1024);
cache.insert(format!("img:/photo/{}.jpg", i), data, metrics);
}
for _ in 0..5 {
let _ = cache.get("api:/users/1");
let _ = cache.get("page:/article/0");
let _ = cache.get("img:/photo/0.jpg");
}
let usage = cache.usage_percentage();
let recommended = cache.recommended_size();
let hit_rate = cache.hit_rate();
black_box((usage, recommended, hit_rate, cache));
});
});
}
criterion_group!(
benches,
bench_cache_creation,
bench_insert_by_content_type,
bench_insert_by_size,
bench_bulk_insert,
bench_get_hit,
bench_get_miss,
bench_repeated_access,
bench_remove,
bench_clear,
bench_stats_queries,
bench_adjust_size_with_eviction,
bench_recommended_size,
bench_eviction_by_priority,
bench_realistic_video_streaming,
bench_realistic_web_content,
);
criterion_main!(benches);