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 // The window tick rides the manual cadence exactly as it
27 // rides the background reaper's — a Manual-mode store
28 // with a windowed table must slide too, not silently
29 // stay all-hot.
30 #[cfg(all(feature = "index", feature = "persist", not(target_arch = "wasm32")))]
31 if let Some(dir) = &self.config.data_dir {
32 let inner = &mut *g;
33 crate::ops_index_window::window_tick(
34 &mut inner.idx_segs,
35 &mut inner.store,
36 &mut inner.aof,
37 &self.tables,
38 &kevy_persist::layout::segs_dir(dir, shard_i),
39 );
40 }
41 g.store.tick_expire(self.config.reaper_samples, self.config.reaper_max_rounds)
42 };
43 total.sampled += stats.sampled;
44 total.expired += stats.expired;
45 // Auto-rewrite rides the caller-driven tick in Manual mode; the
46 // non-blocking path releases the lock for the disk spill.
47 #[cfg(feature = "persist")]
48 crate::reaper::concurrent_auto_rewrite(
49 shard,
50 kevy_persist::RewritePolicy {
51 pct: self.config.auto_aof_rewrite_pct,
52 min_size: self.config.auto_aof_rewrite_min_size,
53 bytes: self.config.auto_aof_rewrite_bytes,
54 interval_secs: self.config.auto_aof_rewrite_interval_secs,
55 },
56 self.config.metric_sink.as_ref(),
57 );
58 }
59 total
60 }
61}