kevy_embedded/store_tick.rs
1//! `Store::tick` — the Manual-mode maintenance cadence, the same
2//! per-shard body the background reaper drives. A `#[path]` child of
3//! `store.rs`, split under the 500-LOC rule.
4
5use kevy_store::ExpireStats;
6
7use crate::store::{Store, lock_write};
8
9impl Store {
10 /// Run one TTL-reaper tick across every shard. Required call cadence in
11 /// `Manual` mode (~10×/s to match Redis `hz=10`). Returns the summed stats.
12 pub fn tick(&self) -> ExpireStats {
13 let mut total = ExpireStats::default();
14 for (shard_i, shard) in self.shards.iter().enumerate() {
15 #[cfg(not(all(feature = "index", feature = "persist", not(target_arch = "wasm32"))))]
16 let _ = shard_i;
17 let stats = {
18 let mut g = lock_write(shard);
19 // Tiering upkeep: budget re-resolution + the index/view
20 // floor feed, then the tick continuation of the
21 // budgeted spill.
22 #[cfg(all(feature = "tier", not(target_arch = "wasm32")))]
23 crate::shard::tier_tick_upkeep(&mut g, self.config.tier_budget, self.shards.len());
24 let _ = g.store.demote_step();
25 let _ = g.store.tier_compact_tick();
26 #[cfg(feature = "index")]
27 crate::ops_index_tidy::tick(&mut g.idx_segs);
28 // The window tick rides the manual cadence exactly as it
29 // rides the background reaper's — a Manual-mode store
30 // with a windowed table must slide too, not silently
31 // stay all-hot.
32 #[cfg(all(feature = "index", feature = "persist", not(target_arch = "wasm32")))]
33 if let Some(dir) = &self.config.data_dir {
34 let inner = &mut *g;
35 crate::ops_index_window::window_tick(
36 &mut inner.idx_segs,
37 &mut inner.store,
38 &mut inner.aof,
39 &self.tables,
40 &kevy_persist::layout::segs_dir(dir, shard_i),
41 );
42 }
43 g.store.tick_expire(self.config.reaper_samples, self.config.reaper_max_rounds)
44 };
45 total.sampled += stats.sampled;
46 total.expired += stats.expired;
47 // Auto-rewrite rides the caller-driven tick in Manual mode; the
48 // non-blocking path releases the lock for the disk spill.
49 #[cfg(feature = "persist")]
50 crate::reaper::concurrent_auto_rewrite(
51 shard,
52 self.config.rewrite_policy(),
53 self.config.metric_sink.as_ref(),
54 );
55 }
56 total
57 }
58}