keyhog_scanner/engine/gpu_cache.rs
1//! GPU matcher on-disk cache helpers and constant-pack types.
2
3/// Cached per-process GPU input constants - pre-packed LE byte streams
4/// for the four pattern-shape inputs the GpuLiteralSet kernel reads on
5/// every dispatch. Filled on first scan, borrowed thereafter.
6pub struct GpuConstPacks {
7 pub pattern_offsets: Vec<u8>,
8 pub pattern_lengths: Vec<u8>,
9 pub pattern_bytes: Vec<u8>,
10 pub pattern_count: Vec<u8>,
11}
12
13/// Cached per-process AC-kernel input constants - pre-packed LE byte
14/// streams for the four DFA-shape inputs the AC bounded-ranges kernel
15/// reads on every dispatch. Separate from `GpuConstPacks` because the
16/// AC kernel binds different fields (`dfa.transitions`,
17/// `dfa.output_offsets`, `dfa.output_records`, `pattern_lengths`).
18pub struct AcConstPacks {
19 pub transitions: Vec<u8>,
20 pub output_offsets: Vec<u8>,
21 pub output_records: Vec<u8>,
22 pub pattern_lengths: Vec<u8>,
23}
24
25/// On-disk cache for `GpuLiteralSet`. The compiled matcher is keyed by a
26/// SHA-256 of the literal set + the vyre wire version (which is bumped
27/// whenever the IR layout changes), so bumping vyre to a new minor
28/// version automatically invalidates the cache instead of silently
29/// loading a stale matcher. Lives at `$XDG_CACHE_HOME/keyhog/programs/`
30/// (typically `~/.cache/keyhog/programs/`).
31const GPU_MATCHER_CACHE_VERSION: u32 = 1;
32
33pub(crate) fn gpu_matcher_cache_dir() -> Option<std::path::PathBuf> {
34 let dir = dirs::cache_dir()?.join("keyhog").join("programs");
35 if !dir.exists() && std::fs::create_dir_all(&dir).is_err() {
36 return None;
37 }
38 Some(dir)
39}
40
41pub(crate) fn gpu_matcher_cache_key(literals: &[&[u8]]) -> String {
42 use sha2::{Digest, Sha256};
43 let mut h = Sha256::new();
44 h.update(GPU_MATCHER_CACHE_VERSION.to_le_bytes());
45 h.update((literals.len() as u32).to_le_bytes());
46 for lit in literals {
47 h.update((lit.len() as u32).to_le_bytes());
48 h.update(lit);
49 }
50 let digest = h.finalize();
51 let mut hex = String::with_capacity(64);
52 for byte in digest {
53 use std::fmt::Write as _;
54 let _ = write!(hex, "{:02x}", byte);
55 }
56 hex
57}