oxilean_kernel/whnf_memo/types.rs
1//! Types for the memoized WHNF reduction layer.
2//!
3//! Provides cache key/entry/configuration/statistics types for the WHNF memo
4//! table. Cache correctness is guaranteed by including the current environment
5//! version in every key: when the environment grows (a new declaration is
6//! added), `invalidate_all` bumps `env_version`, rendering all prior entries
7//! stale without requiring an explicit scan.
8
9use std::collections::HashMap;
10
11// ---------------------------------------------------------------------------
12// WhnfKey
13// ---------------------------------------------------------------------------
14
15/// Cache key for a single WHNF reduction result.
16///
17/// Including `env_version` ensures that cached reductions are invalidated
18/// automatically when the environment changes: a key computed under version `v`
19/// will never match an entry stored under version `v'` where `v' != v`.
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
21pub struct WhnfKey {
22 /// FNV-1a hash of the expression bytes to be reduced.
23 pub expr_hash: u64,
24 /// Monotonically increasing environment version at query time.
25 pub env_version: u32,
26}
27
28// ---------------------------------------------------------------------------
29// WhnfEntry
30// ---------------------------------------------------------------------------
31
32/// A single cached WHNF reduction result.
33#[derive(Clone, Debug, PartialEq, Eq)]
34pub struct WhnfEntry {
35 /// FNV-1a hash of the WHNF-reduced result expression.
36 pub result_hash: u64,
37 /// Number of reduction steps performed to reach WHNF (used for eviction
38 /// decisions: entries that required few steps are cheap to recompute).
39 pub reduction_steps: u32,
40 /// Number of times this entry has been returned from the cache.
41 pub access_count: u32,
42}
43
44// ---------------------------------------------------------------------------
45// MemoConfig
46// ---------------------------------------------------------------------------
47
48/// Configuration parameters for a [`WhnfMemo`] instance.
49#[derive(Clone, Debug)]
50pub struct MemoConfig {
51 /// Maximum number of entries in the cache before eviction is triggered.
52 pub max_entries: usize,
53 /// Minimum number of reduction steps required before a result is cached.
54 ///
55 /// Results achieved in fewer steps are cheap to recompute and not worth
56 /// the memory overhead.
57 pub min_steps_to_cache: u32,
58 /// Fraction of `max_entries` used as the access-count threshold during
59 /// cold eviction. Entries whose `access_count` is below
60 /// `floor(max_entries * eviction_threshold)` are considered cold and may
61 /// be removed.
62 pub eviction_threshold: f64,
63}
64
65impl Default for MemoConfig {
66 fn default() -> Self {
67 MemoConfig {
68 max_entries: 4096,
69 min_steps_to_cache: 2,
70 eviction_threshold: 0.1,
71 }
72 }
73}
74
75// ---------------------------------------------------------------------------
76// WhnfMemo
77// ---------------------------------------------------------------------------
78
79/// Memoization table for WHNF reduction results.
80///
81/// # Correctness
82///
83/// Every lookup and insertion is tied to `env_version`. Calling
84/// `invalidate_all` bumps the version and clears all entries, guaranteeing
85/// that stale results (computed against an older environment) are never
86/// returned.
87///
88/// # Eviction
89///
90/// When the table reaches `config.max_entries`, `evict_cold` is called
91/// automatically during `insert`. Cold entries — those whose `access_count`
92/// falls below a threshold derived from `config.eviction_threshold` — are
93/// removed. If no cold entries exist the oldest-inserted entry is dropped.
94pub struct WhnfMemo {
95 /// Cached entries, keyed by (expression hash, env version).
96 pub(crate) entries: HashMap<WhnfKey, WhnfEntry>,
97 /// Total number of successful cache lookups.
98 pub hits: u64,
99 /// Total number of cache misses.
100 pub misses: u64,
101 /// Total number of entries removed by eviction.
102 pub evictions: u64,
103 /// Current environment version.
104 pub env_version: u32,
105 /// Configuration controlling capacity, caching threshold, and eviction.
106 pub(crate) config: MemoConfig,
107 /// Monotonically increasing insertion counter (used to implement FIFO
108 /// fallback eviction when no cold entries are found).
109 pub(crate) insert_order: Vec<WhnfKey>,
110}
111
112// ---------------------------------------------------------------------------
113// MemoStats
114// ---------------------------------------------------------------------------
115
116/// A snapshot of [`WhnfMemo`] performance statistics.
117#[derive(Clone, Debug)]
118pub struct MemoStats {
119 /// Total cache hits.
120 pub hits: u64,
121 /// Total cache misses.
122 pub misses: u64,
123 /// Total evictions.
124 pub evictions: u64,
125 /// Hit rate in [0.0, 1.0].
126 pub hit_rate: f64,
127 /// Current number of cached entries.
128 pub size: usize,
129 /// Current environment version.
130 pub env_version: u32,
131}
132
133impl std::fmt::Display for MemoStats {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 write!(
136 f,
137 "MemoStats {{ hits: {}, misses: {}, evictions: {}, hit_rate: {:.2}%, size: {}, env_version: {} }}",
138 self.hits,
139 self.misses,
140 self.evictions,
141 self.hit_rate * 100.0,
142 self.size,
143 self.env_version
144 )
145 }
146}