use chie_core::cache_invalidation::{
InvalidationEvent, InvalidationNotifier, InvalidationPattern, InvalidationReason,
};
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use std::collections::HashSet;
use std::hint::black_box;
fn bench_event_creation(c: &mut Criterion) {
let mut group = c.benchmark_group("event_creation");
let reasons = vec![
("updated", InvalidationReason::Updated),
("deleted", InvalidationReason::Deleted),
("expired", InvalidationReason::Expired),
("manual", InvalidationReason::Manual),
("error", InvalidationReason::Error),
("memory_pressure", InvalidationReason::MemoryPressure),
];
for (name, reason) in reasons {
group.bench_function(name, |b| {
b.iter(|| {
let event = InvalidationEvent::new(
black_box("content:QmTest123".to_string()),
black_box(reason.clone()),
);
black_box(event)
});
});
}
group.finish();
}
fn bench_event_with_metadata(c: &mut Criterion) {
let mut group = c.benchmark_group("event_with_metadata");
group.bench_function("single_metadata", |b| {
b.iter(|| {
let event = InvalidationEvent::new(
black_box("content:QmTest123".to_string()),
black_box(InvalidationReason::Updated),
)
.with_metadata(
black_box("version".to_string()),
black_box("2.0".to_string()),
);
black_box(event)
});
});
group.bench_function("multiple_metadata", |b| {
b.iter(|| {
let event = InvalidationEvent::new(
black_box("content:QmTest123".to_string()),
black_box(InvalidationReason::Updated),
)
.with_metadata(
black_box("version".to_string()),
black_box("2.0".to_string()),
)
.with_metadata(
black_box("author".to_string()),
black_box("user123".to_string()),
)
.with_metadata(
black_box("timestamp".to_string()),
black_box("2024-01-01".to_string()),
);
black_box(event)
});
});
group.finish();
}
fn bench_event_with_origin(c: &mut Criterion) {
let mut group = c.benchmark_group("event_with_origin");
group.bench_function("set_origin", |b| {
b.iter(|| {
let event = InvalidationEvent::new(
black_box("content:QmTest123".to_string()),
black_box(InvalidationReason::Updated),
)
.with_origin(black_box("node_abc123".to_string()));
black_box(event)
});
});
group.finish();
}
fn bench_pattern_matching(c: &mut Criterion) {
let mut group = c.benchmark_group("pattern_matching");
let test_key = "content:QmTest123:metadata";
group.bench_function("exact_match", |b| {
let pattern = InvalidationPattern::Exact(test_key.to_string());
b.iter(|| {
let matches = pattern.matches(black_box(test_key));
black_box(matches)
});
});
group.bench_function("prefix_match", |b| {
let pattern = InvalidationPattern::Prefix("content:".to_string());
b.iter(|| {
let matches = pattern.matches(black_box(test_key));
black_box(matches)
});
});
group.bench_function("suffix_match", |b| {
let pattern = InvalidationPattern::Suffix(":metadata".to_string());
b.iter(|| {
let matches = pattern.matches(black_box(test_key));
black_box(matches)
});
});
group.bench_function("contains_match", |b| {
let pattern = InvalidationPattern::Contains("QmTest".to_string());
b.iter(|| {
let matches = pattern.matches(black_box(test_key));
black_box(matches)
});
});
group.finish();
}
fn bench_pattern_matching_bulk(c: &mut Criterion) {
let mut group = c.benchmark_group("pattern_matching_bulk");
let sizes = vec![10, 100, 1000];
for size in sizes {
group.throughput(Throughput::Elements(size as u64));
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_keys", size)),
&size,
|b, &size| {
let keys: Vec<String> = (0..size)
.map(|i| format!("content:QmTest{}:metadata", i))
.collect();
let pattern = InvalidationPattern::Prefix("content:".to_string());
b.iter(|| {
let mut matched = 0;
for key in &keys {
if pattern.matches(black_box(key)) {
matched += 1;
}
}
black_box(matched)
});
},
);
}
group.finish();
}
fn bench_notifier_creation(c: &mut Criterion) {
let mut group = c.benchmark_group("notifier_creation");
group.bench_function("create_notifier", |b| {
b.iter(|| {
let notifier = InvalidationNotifier::new();
black_box(notifier)
});
});
group.finish();
}
fn bench_subscription(c: &mut Criterion) {
let mut group = c.benchmark_group("subscription");
group.bench_function("single_subscription", |b| {
let notifier = InvalidationNotifier::new();
b.iter(|| {
let receiver = notifier.subscribe();
black_box(receiver)
});
});
group.bench_function("multiple_subscriptions", |b| {
let notifier = InvalidationNotifier::new();
b.iter(|| {
let receivers: Vec<_> = (0..10).map(|_| notifier.subscribe()).collect();
black_box(receivers)
});
});
group.finish();
}
fn bench_subscriber_count(c: &mut Criterion) {
let mut group = c.benchmark_group("subscriber_count");
let counts = vec![0, 1, 10, 100];
for count in counts {
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_subscribers", count)),
&count,
|b, &count| {
let notifier = InvalidationNotifier::new();
let _receivers: Vec<_> = (0..count).map(|_| notifier.subscribe()).collect();
b.iter(|| {
let sub_count = notifier.subscriber_count();
black_box(sub_count)
});
},
);
}
group.finish();
}
fn bench_pattern_creation(c: &mut Criterion) {
let mut group = c.benchmark_group("pattern_creation");
group.bench_function("exact_pattern", |b| {
b.iter(|| {
let pattern = InvalidationPattern::Exact(black_box("key".to_string()));
black_box(pattern)
});
});
group.bench_function("prefix_pattern", |b| {
b.iter(|| {
let pattern = InvalidationPattern::Prefix(black_box("prefix:".to_string()));
black_box(pattern)
});
});
group.bench_function("suffix_pattern", |b| {
b.iter(|| {
let pattern = InvalidationPattern::Suffix(black_box(":suffix".to_string()));
black_box(pattern)
});
});
group.bench_function("contains_pattern", |b| {
b.iter(|| {
let pattern = InvalidationPattern::Contains(black_box("substring".to_string()));
black_box(pattern)
});
});
group.bench_function("tags_pattern", |b| {
let tags: HashSet<String> =
vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()]
.into_iter()
.collect();
b.iter(|| {
let pattern = InvalidationPattern::Tags(black_box(tags.clone()));
black_box(pattern)
});
});
group.finish();
}
fn bench_pattern_key_lengths(c: &mut Criterion) {
let mut group = c.benchmark_group("pattern_key_lengths");
let lengths = vec![10, 50, 100, 500];
for length in lengths {
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_chars", length)),
&length,
|b, &length| {
let key = "a".repeat(length);
let pattern = InvalidationPattern::Prefix("a".to_string());
b.iter(|| {
let matches = pattern.matches(black_box(&key));
black_box(matches)
});
},
);
}
group.finish();
}
fn bench_event_full_chain(c: &mut Criterion) {
let mut group = c.benchmark_group("event_full_chain");
group.bench_function("complete_event", |b| {
b.iter(|| {
let event = InvalidationEvent::new(
black_box("content:QmTest123:v2:metadata".to_string()),
black_box(InvalidationReason::Updated),
)
.with_metadata(
black_box("version".to_string()),
black_box("2.0".to_string()),
)
.with_metadata(
black_box("author".to_string()),
black_box("user123".to_string()),
)
.with_metadata(black_box("size".to_string()), black_box("1024".to_string()))
.with_origin(black_box("node_xyz789".to_string()));
black_box(event)
});
});
group.finish();
}
fn bench_realistic_scenarios(c: &mut Criterion) {
let mut group = c.benchmark_group("realistic_scenarios");
group.bench_function("content_update", |b| {
b.iter(|| {
let keys: Vec<String> = (0..10)
.map(|i| format!("content:QmTest{}:metadata", i))
.collect();
let pattern = InvalidationPattern::Prefix("content:QmTest5".to_string());
let mut invalidated = Vec::new();
for key in &keys {
if pattern.matches(key) {
let event = InvalidationEvent::new(key.clone(), InvalidationReason::Updated);
invalidated.push(event);
}
}
black_box(invalidated)
});
});
group.bench_function("batch_expiration", |b| {
b.iter(|| {
let events: Vec<_> = (0..100)
.map(|i| {
InvalidationEvent::new(
format!("temp:session_{}", i),
InvalidationReason::Expired,
)
})
.collect();
black_box(events)
});
});
group.finish();
}
criterion_group!(
benches,
bench_event_creation,
bench_event_with_metadata,
bench_event_with_origin,
bench_pattern_matching,
bench_pattern_matching_bulk,
bench_notifier_creation,
bench_subscription,
bench_subscriber_count,
bench_pattern_creation,
bench_pattern_key_lengths,
bench_event_full_chain,
bench_realistic_scenarios,
);
criterion_main!(benches);