atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git

Blame: benchmarks/benches/linked_chunk.rs

7ff8adafe9e4atagen2026-10-22 12:30 UTC1
use std::{sync::Arc, time::Duration};
7ff8adafe9e4atagen2026-10-22 12:30 UTC2
7ff8adafe9e4atagen2026-10-22 12:30 UTC3
use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
7ff8adafe9e4atagen2026-10-22 12:30 UTC4
use matrix_sdk::{
7ff8adafe9e4atagen2026-10-22 12:30 UTC5
    SqliteEventCacheStore,
7ff8adafe9e4atagen2026-10-22 12:30 UTC6
    linked_chunk::{LinkedChunk, LinkedChunkId, Update, lazy_loader},
7ff8adafe9e4atagen2026-10-22 12:30 UTC7
};
7ff8adafe9e4atagen2026-10-22 12:30 UTC8
use matrix_sdk_base::event_cache::{
7ff8adafe9e4atagen2026-10-22 12:30 UTC9
    Event, Gap,
7ff8adafe9e4atagen2026-10-22 12:30 UTC10
    store::{DEFAULT_CHUNK_CAPACITY, DynEventCacheStore, IntoEventCacheStore, MemoryStore},
7ff8adafe9e4atagen2026-10-22 12:30 UTC11
};
7ff8adafe9e4atagen2026-10-22 12:30 UTC12
use matrix_sdk_test::{ALICE, event_factory::EventFactory};
7ff8adafe9e4atagen2026-10-22 12:30 UTC13
use ruma::room_id;
7ff8adafe9e4atagen2026-10-22 12:30 UTC14
use tempfile::tempdir;
7ff8adafe9e4atagen2026-10-22 12:30 UTC15
use tokio::runtime::Builder;
7ff8adafe9e4atagen2026-10-22 12:30 UTC16
7ff8adafe9e4atagen2026-10-22 12:30 UTC17
#[derive(Clone, Debug)]
7ff8adafe9e4atagen2026-10-22 12:30 UTC18
enum Operation {
7ff8adafe9e4atagen2026-10-22 12:30 UTC19
    PushItemsBack(Vec<Event>),
7ff8adafe9e4atagen2026-10-22 12:30 UTC20
    PushGapBack(Gap),
7ff8adafe9e4atagen2026-10-22 12:30 UTC21
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC22
7ff8adafe9e4atagen2026-10-22 12:30 UTC23
#[cfg(not(feature = "codspeed"))]
7ff8adafe9e4atagen2026-10-22 12:30 UTC24
const NUMBER_OF_EVENTS: &[u64] = &[10, 100, 1000, 10_000, 100_000];
7ff8adafe9e4atagen2026-10-22 12:30 UTC25
#[cfg(feature = "codspeed")]
7ff8adafe9e4atagen2026-10-22 12:30 UTC26
const NUMBER_OF_EVENTS: &[u64] = &[10, 100, 1000];
7ff8adafe9e4atagen2026-10-22 12:30 UTC27
7ff8adafe9e4atagen2026-10-22 12:30 UTC28
fn writing(c: &mut Criterion) {
7ff8adafe9e4atagen2026-10-22 12:30 UTC29
    // Create a new asynchronous runtime.
7ff8adafe9e4atagen2026-10-22 12:30 UTC30
    let runtime = Builder::new_multi_thread()
7ff8adafe9e4atagen2026-10-22 12:30 UTC31
        .enable_time()
7ff8adafe9e4atagen2026-10-22 12:30 UTC32
        .enable_io()
7ff8adafe9e4atagen2026-10-22 12:30 UTC33
        .build()
7ff8adafe9e4atagen2026-10-22 12:30 UTC34
        .expect("Failed to create an asynchronous runtime");
7ff8adafe9e4atagen2026-10-22 12:30 UTC35
7ff8adafe9e4atagen2026-10-22 12:30 UTC36
    let room_id = room_id!("!fabricandofitfaber:bar.baz");
7ff8adafe9e4atagen2026-10-22 12:30 UTC37
    let linked_chunk_id = LinkedChunkId::Room(room_id);
7ff8adafe9e4atagen2026-10-22 12:30 UTC38
    let event_factory = EventFactory::new().room(room_id).sender(&ALICE);
7ff8adafe9e4atagen2026-10-22 12:30 UTC39
7ff8adafe9e4atagen2026-10-22 12:30 UTC40
    let mut group = c.benchmark_group("Linked chunk writing");
7ff8adafe9e4atagen2026-10-22 12:30 UTC41
    group.sample_size(10).measurement_time(Duration::from_secs(30));
7ff8adafe9e4atagen2026-10-22 12:30 UTC42
7ff8adafe9e4atagen2026-10-22 12:30 UTC43
    for &number_of_events in NUMBER_OF_EVENTS {
7ff8adafe9e4atagen2026-10-22 12:30 UTC44
        let sqlite_temp_dir = tempdir().unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC45
7ff8adafe9e4atagen2026-10-22 12:30 UTC46
        // Declare new stores for this set of events.
7ff8adafe9e4atagen2026-10-22 12:30 UTC47
        let stores: [(&str, Option<Arc<DynEventCacheStore>>); 3] = [
7ff8adafe9e4atagen2026-10-22 12:30 UTC48
            ("none", None),
7ff8adafe9e4atagen2026-10-22 12:30 UTC49
            ("memory store", Some(MemoryStore::default().into_event_cache_store())),
7ff8adafe9e4atagen2026-10-22 12:30 UTC50
            (
7ff8adafe9e4atagen2026-10-22 12:30 UTC51
                "sqlite store",
7ff8adafe9e4atagen2026-10-22 12:30 UTC52
                runtime.block_on(async {
7ff8adafe9e4atagen2026-10-22 12:30 UTC53
                    Some(
7ff8adafe9e4atagen2026-10-22 12:30 UTC54
                        SqliteEventCacheStore::open(sqlite_temp_dir.path().join("bench"), None)
7ff8adafe9e4atagen2026-10-22 12:30 UTC55
                            .await
7ff8adafe9e4atagen2026-10-22 12:30 UTC56
                            .unwrap()
7ff8adafe9e4atagen2026-10-22 12:30 UTC57
                            .into_event_cache_store(),
7ff8adafe9e4atagen2026-10-22 12:30 UTC58
                    )
7ff8adafe9e4atagen2026-10-22 12:30 UTC59
                }),
7ff8adafe9e4atagen2026-10-22 12:30 UTC60
            ),
7ff8adafe9e4atagen2026-10-22 12:30 UTC61
        ];
7ff8adafe9e4atagen2026-10-22 12:30 UTC62
7ff8adafe9e4atagen2026-10-22 12:30 UTC63
        for (store_name, store) in stores {
7ff8adafe9e4atagen2026-10-22 12:30 UTC64
            // Create the operations we want to bench.
7ff8adafe9e4atagen2026-10-22 12:30 UTC65
            let mut operations = Vec::new();
7ff8adafe9e4atagen2026-10-22 12:30 UTC66
7ff8adafe9e4atagen2026-10-22 12:30 UTC67
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC68
                let mut events = (0..number_of_events)
7ff8adafe9e4atagen2026-10-22 12:30 UTC69
                    .map(|nth| event_factory.text_msg(format!("foo {nth}")).into_event())
7ff8adafe9e4atagen2026-10-22 12:30 UTC70
                    .peekable();
7ff8adafe9e4atagen2026-10-22 12:30 UTC71
7ff8adafe9e4atagen2026-10-22 12:30 UTC72
                let mut gap_nth = 0;
7ff8adafe9e4atagen2026-10-22 12:30 UTC73
7ff8adafe9e4atagen2026-10-22 12:30 UTC74
                while events.peek().is_some() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC75
                    {
7ff8adafe9e4atagen2026-10-22 12:30 UTC76
                        let events_to_push_back = events.by_ref().take(80).collect::<Vec<_>>();
7ff8adafe9e4atagen2026-10-22 12:30 UTC77
7ff8adafe9e4atagen2026-10-22 12:30 UTC78
                        if events_to_push_back.is_empty() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC79
                            break;
7ff8adafe9e4atagen2026-10-22 12:30 UTC80
                        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC81
7ff8adafe9e4atagen2026-10-22 12:30 UTC82
                        operations.push(Operation::PushItemsBack(events_to_push_back));
7ff8adafe9e4atagen2026-10-22 12:30 UTC83
                    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC84
7ff8adafe9e4atagen2026-10-22 12:30 UTC85
                    {
49a9cd1aff19atagen2026-10-25 05:37 UTC86
                        operations.push(Operation::PushGapBack(Gap {
49a9cd1aff19atagen2026-10-25 05:37 UTC87
                            token: format!("gap{gap_nth}"),
49a9cd1aff19atagen2026-10-25 05:37 UTC88
                            history: None,
49a9cd1aff19atagen2026-10-25 05:37 UTC89
                        }));
7ff8adafe9e4atagen2026-10-22 12:30 UTC90
                        gap_nth += 1;
7ff8adafe9e4atagen2026-10-22 12:30 UTC91
                    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC92
                }
7ff8adafe9e4atagen2026-10-22 12:30 UTC93
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC94
7ff8adafe9e4atagen2026-10-22 12:30 UTC95
            // Define the throughput.
7ff8adafe9e4atagen2026-10-22 12:30 UTC96
            group.throughput(Throughput::Elements(number_of_events));
7ff8adafe9e4atagen2026-10-22 12:30 UTC97
7ff8adafe9e4atagen2026-10-22 12:30 UTC98
            // Get a bencher.
7ff8adafe9e4atagen2026-10-22 12:30 UTC99
            group.bench_with_input(
7ff8adafe9e4atagen2026-10-22 12:30 UTC100
                BenchmarkId::new(format!("Linked chunk writing [{store_name}]"), number_of_events),
7ff8adafe9e4atagen2026-10-22 12:30 UTC101
                &operations,
7ff8adafe9e4atagen2026-10-22 12:30 UTC102
                |bencher, operations| {
7ff8adafe9e4atagen2026-10-22 12:30 UTC103
                    // Bench the routine.
7ff8adafe9e4atagen2026-10-22 12:30 UTC104
                    bencher.to_async(&runtime).iter_batched(
7ff8adafe9e4atagen2026-10-22 12:30 UTC105
                        || operations.clone(),
7ff8adafe9e4atagen2026-10-22 12:30 UTC106
                        |operations| async {
7ff8adafe9e4atagen2026-10-22 12:30 UTC107
                            // The routine to bench!
7ff8adafe9e4atagen2026-10-22 12:30 UTC108
7ff8adafe9e4atagen2026-10-22 12:30 UTC109
                            let mut linked_chunk = LinkedChunk::<DEFAULT_CHUNK_CAPACITY, Event, Gap>::new_with_update_history();
7ff8adafe9e4atagen2026-10-22 12:30 UTC110
7ff8adafe9e4atagen2026-10-22 12:30 UTC111
                            for operation in operations {
7ff8adafe9e4atagen2026-10-22 12:30 UTC112
                                match operation {
7ff8adafe9e4atagen2026-10-22 12:30 UTC113
                                    Operation::PushItemsBack(events) => linked_chunk.push_items_back(events),
7ff8adafe9e4atagen2026-10-22 12:30 UTC114
                                    Operation::PushGapBack(gap) => linked_chunk.push_gap_back(gap),
7ff8adafe9e4atagen2026-10-22 12:30 UTC115
                                }
7ff8adafe9e4atagen2026-10-22 12:30 UTC116
                            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC117
7ff8adafe9e4atagen2026-10-22 12:30 UTC118
                            if let Some(store) = &store {
7ff8adafe9e4atagen2026-10-22 12:30 UTC119
                                let updates = linked_chunk.updates().unwrap().take();
7ff8adafe9e4atagen2026-10-22 12:30 UTC120
                                store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC121
                                // Empty the store.
7ff8adafe9e4atagen2026-10-22 12:30 UTC122
                                store.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear]).await.unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC123
                            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC124
7ff8adafe9e4atagen2026-10-22 12:30 UTC125
                        },
7ff8adafe9e4atagen2026-10-22 12:30 UTC126
                        BatchSize::SmallInput
7ff8adafe9e4atagen2026-10-22 12:30 UTC127
                    )
7ff8adafe9e4atagen2026-10-22 12:30 UTC128
                },
7ff8adafe9e4atagen2026-10-22 12:30 UTC129
            );
7ff8adafe9e4atagen2026-10-22 12:30 UTC130
7ff8adafe9e4atagen2026-10-22 12:30 UTC131
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC132
                let _guard = runtime.enter();
7ff8adafe9e4atagen2026-10-22 12:30 UTC133
                drop(store);
7ff8adafe9e4atagen2026-10-22 12:30 UTC134
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC135
        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC136
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC137
7ff8adafe9e4atagen2026-10-22 12:30 UTC138
    group.finish()
7ff8adafe9e4atagen2026-10-22 12:30 UTC139
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC140
7ff8adafe9e4atagen2026-10-22 12:30 UTC141
fn reading(c: &mut Criterion) {
7ff8adafe9e4atagen2026-10-22 12:30 UTC142
    // Create a new asynchronous runtime.
7ff8adafe9e4atagen2026-10-22 12:30 UTC143
    let runtime = Builder::new_multi_thread()
7ff8adafe9e4atagen2026-10-22 12:30 UTC144
        .enable_time()
7ff8adafe9e4atagen2026-10-22 12:30 UTC145
        .enable_io()
7ff8adafe9e4atagen2026-10-22 12:30 UTC146
        .build()
7ff8adafe9e4atagen2026-10-22 12:30 UTC147
        .expect("Failed to create an asynchronous runtime");
7ff8adafe9e4atagen2026-10-22 12:30 UTC148
7ff8adafe9e4atagen2026-10-22 12:30 UTC149
    let room_id = room_id!("!fabricandofitfaber:bar.baz");
7ff8adafe9e4atagen2026-10-22 12:30 UTC150
    let linked_chunk_id = LinkedChunkId::Room(room_id);
7ff8adafe9e4atagen2026-10-22 12:30 UTC151
    let event_factory = EventFactory::new().room(room_id).sender(&ALICE);
7ff8adafe9e4atagen2026-10-22 12:30 UTC152
7ff8adafe9e4atagen2026-10-22 12:30 UTC153
    let mut group = c.benchmark_group("Linked chunk reading");
7ff8adafe9e4atagen2026-10-22 12:30 UTC154
    group.sample_size(10);
7ff8adafe9e4atagen2026-10-22 12:30 UTC155
7ff8adafe9e4atagen2026-10-22 12:30 UTC156
    for &num_events in NUMBER_OF_EVENTS {
7ff8adafe9e4atagen2026-10-22 12:30 UTC157
        let sqlite_temp_dir = tempdir().unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC158
7ff8adafe9e4atagen2026-10-22 12:30 UTC159
        // Declare new stores for this set of events.
7ff8adafe9e4atagen2026-10-22 12:30 UTC160
        let stores: [(&str, Arc<DynEventCacheStore>); 2] = [
7ff8adafe9e4atagen2026-10-22 12:30 UTC161
            ("memory store", MemoryStore::default().into_event_cache_store()),
7ff8adafe9e4atagen2026-10-22 12:30 UTC162
            (
7ff8adafe9e4atagen2026-10-22 12:30 UTC163
                "sqlite store",
7ff8adafe9e4atagen2026-10-22 12:30 UTC164
                runtime.block_on(async {
7ff8adafe9e4atagen2026-10-22 12:30 UTC165
                    SqliteEventCacheStore::open(sqlite_temp_dir.path().join("bench"), None)
7ff8adafe9e4atagen2026-10-22 12:30 UTC166
                        .await
7ff8adafe9e4atagen2026-10-22 12:30 UTC167
                        .unwrap()
7ff8adafe9e4atagen2026-10-22 12:30 UTC168
                        .into_event_cache_store()
7ff8adafe9e4atagen2026-10-22 12:30 UTC169
                }),
7ff8adafe9e4atagen2026-10-22 12:30 UTC170
            ),
7ff8adafe9e4atagen2026-10-22 12:30 UTC171
        ];
7ff8adafe9e4atagen2026-10-22 12:30 UTC172
7ff8adafe9e4atagen2026-10-22 12:30 UTC173
        for (store_name, store) in stores {
7ff8adafe9e4atagen2026-10-22 12:30 UTC174
            // Store some events and gap chunks in the store.
7ff8adafe9e4atagen2026-10-22 12:30 UTC175
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC176
                let mut events = (0..num_events)
7ff8adafe9e4atagen2026-10-22 12:30 UTC177
                    .map(|nth| event_factory.text_msg(format!("foo {nth}")).into_event())
7ff8adafe9e4atagen2026-10-22 12:30 UTC178
                    .peekable();
7ff8adafe9e4atagen2026-10-22 12:30 UTC179
7ff8adafe9e4atagen2026-10-22 12:30 UTC180
                let mut lc =
7ff8adafe9e4atagen2026-10-22 12:30 UTC181
                    LinkedChunk::<DEFAULT_CHUNK_CAPACITY, Event, Gap>::new_with_update_history();
7ff8adafe9e4atagen2026-10-22 12:30 UTC182
                let mut num_gaps = 0;
7ff8adafe9e4atagen2026-10-22 12:30 UTC183
7ff8adafe9e4atagen2026-10-22 12:30 UTC184
                while events.peek().is_some() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC185
                    let events_chunk = events.by_ref().take(80).collect::<Vec<_>>();
7ff8adafe9e4atagen2026-10-22 12:30 UTC186
7ff8adafe9e4atagen2026-10-22 12:30 UTC187
                    if events_chunk.is_empty() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC188
                        break;
7ff8adafe9e4atagen2026-10-22 12:30 UTC189
                    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC190
7ff8adafe9e4atagen2026-10-22 12:30 UTC191
                    lc.push_items_back(events_chunk);
49a9cd1aff19atagen2026-10-25 05:37 UTC192
                    lc.push_gap_back(Gap { token: format!("gap{num_gaps}"), history: None });
7ff8adafe9e4atagen2026-10-22 12:30 UTC193
7ff8adafe9e4atagen2026-10-22 12:30 UTC194
                    num_gaps += 1;
7ff8adafe9e4atagen2026-10-22 12:30 UTC195
                }
7ff8adafe9e4atagen2026-10-22 12:30 UTC196
7ff8adafe9e4atagen2026-10-22 12:30 UTC197
                // Now persist the updates to recreate this full linked chunk.
7ff8adafe9e4atagen2026-10-22 12:30 UTC198
                let updates = lc.updates().unwrap().take();
7ff8adafe9e4atagen2026-10-22 12:30 UTC199
                runtime
7ff8adafe9e4atagen2026-10-22 12:30 UTC200
                    .block_on(store.handle_linked_chunk_updates(linked_chunk_id, updates))
7ff8adafe9e4atagen2026-10-22 12:30 UTC201
                    .unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC202
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC203
7ff8adafe9e4atagen2026-10-22 12:30 UTC204
            // Define the throughput.
7ff8adafe9e4atagen2026-10-22 12:30 UTC205
            group.throughput(Throughput::Elements(num_events));
7ff8adafe9e4atagen2026-10-22 12:30 UTC206
7ff8adafe9e4atagen2026-10-22 12:30 UTC207
            // Bench the lazy loader.
7ff8adafe9e4atagen2026-10-22 12:30 UTC208
            group.bench_function(
7ff8adafe9e4atagen2026-10-22 12:30 UTC209
                BenchmarkId::new(format!("Linked chunk lazy loader[{store_name}]"), num_events),
7ff8adafe9e4atagen2026-10-22 12:30 UTC210
                |bencher| {
7ff8adafe9e4atagen2026-10-22 12:30 UTC211
                    // Bench the routine.
7ff8adafe9e4atagen2026-10-22 12:30 UTC212
                    bencher.to_async(&runtime).iter(|| async {
7ff8adafe9e4atagen2026-10-22 12:30 UTC213
                        // Load the last chunk first,
7ff8adafe9e4atagen2026-10-22 12:30 UTC214
                        let (last_chunk, chunk_id_gen) =
7ff8adafe9e4atagen2026-10-22 12:30 UTC215
                            store.load_last_chunk(linked_chunk_id).await.unwrap();
7ff8adafe9e4atagen2026-10-22 12:30 UTC216
7ff8adafe9e4atagen2026-10-22 12:30 UTC217
                        let mut lc =
7ff8adafe9e4atagen2026-10-22 12:30 UTC218
                            lazy_loader::from_last_chunk::<128, _, _>(last_chunk, chunk_id_gen)
7ff8adafe9e4atagen2026-10-22 12:30 UTC219
                                .expect("no error when reconstructing the linked chunk")
7ff8adafe9e4atagen2026-10-22 12:30 UTC220
                                .expect("there is a linked chunk in the store");
7ff8adafe9e4atagen2026-10-22 12:30 UTC221
7ff8adafe9e4atagen2026-10-22 12:30 UTC222
                        // Then load until the start of the linked chunk.
7ff8adafe9e4atagen2026-10-22 12:30 UTC223
                        let mut cur_chunk_id = lc.chunks().next().unwrap().identifier();
7ff8adafe9e4atagen2026-10-22 12:30 UTC224
                        while let Some(prev) =
7ff8adafe9e4atagen2026-10-22 12:30 UTC225
                            store.load_previous_chunk(linked_chunk_id, cur_chunk_id).await.unwrap()
7ff8adafe9e4atagen2026-10-22 12:30 UTC226
                        {
7ff8adafe9e4atagen2026-10-22 12:30 UTC227
                            cur_chunk_id = prev.identifier;
7ff8adafe9e4atagen2026-10-22 12:30 UTC228
                            lazy_loader::insert_new_first_chunk(&mut lc, prev)
7ff8adafe9e4atagen2026-10-22 12:30 UTC229
                                .expect("no error when linking the previous lazy-loaded chunk");
7ff8adafe9e4atagen2026-10-22 12:30 UTC230
                        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC231
                    })
7ff8adafe9e4atagen2026-10-22 12:30 UTC232
                },
7ff8adafe9e4atagen2026-10-22 12:30 UTC233
            );
7ff8adafe9e4atagen2026-10-22 12:30 UTC234
7ff8adafe9e4atagen2026-10-22 12:30 UTC235
            // Bench the metadata loader.
7ff8adafe9e4atagen2026-10-22 12:30 UTC236
            group.bench_function(
7ff8adafe9e4atagen2026-10-22 12:30 UTC237
                BenchmarkId::new(format!("Linked chunk metadata loader[{store_name}]"), num_events),
7ff8adafe9e4atagen2026-10-22 12:30 UTC238
                |bencher| {
7ff8adafe9e4atagen2026-10-22 12:30 UTC239
                    // Bench the routine.
7ff8adafe9e4atagen2026-10-22 12:30 UTC240
                    bencher.to_async(&runtime).iter(|| async {
7ff8adafe9e4atagen2026-10-22 12:30 UTC241
                        let _metadata = store
7ff8adafe9e4atagen2026-10-22 12:30 UTC242
                            .load_all_chunks_metadata(linked_chunk_id)
7ff8adafe9e4atagen2026-10-22 12:30 UTC243
                            .await
7ff8adafe9e4atagen2026-10-22 12:30 UTC244
                            .expect("metadata must load");
7ff8adafe9e4atagen2026-10-22 12:30 UTC245
                    })
7ff8adafe9e4atagen2026-10-22 12:30 UTC246
                },
7ff8adafe9e4atagen2026-10-22 12:30 UTC247
            );
7ff8adafe9e4atagen2026-10-22 12:30 UTC248
7ff8adafe9e4atagen2026-10-22 12:30 UTC249
            {
7ff8adafe9e4atagen2026-10-22 12:30 UTC250
                let _guard = runtime.enter();
7ff8adafe9e4atagen2026-10-22 12:30 UTC251
                drop(store);
7ff8adafe9e4atagen2026-10-22 12:30 UTC252
            }
7ff8adafe9e4atagen2026-10-22 12:30 UTC253
        }
7ff8adafe9e4atagen2026-10-22 12:30 UTC254
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC255
7ff8adafe9e4atagen2026-10-22 12:30 UTC256
    group.finish()
7ff8adafe9e4atagen2026-10-22 12:30 UTC257
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC258
7ff8adafe9e4atagen2026-10-22 12:30 UTC259
criterion_group! {
7ff8adafe9e4atagen2026-10-22 12:30 UTC260
    name = event_cache;
7ff8adafe9e4atagen2026-10-22 12:30 UTC261
    config = Criterion::default();
7ff8adafe9e4atagen2026-10-22 12:30 UTC262
    targets = writing, reading,
7ff8adafe9e4atagen2026-10-22 12:30 UTC263
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC264
7ff8adafe9e4atagen2026-10-22 12:30 UTC265
criterion_main!(event_cache);