crush_gpu/scorer.rs
1//! Eligibility scoring for GPU compression plugin selection
2//!
3//! Evaluates three criteria to decide if the GPU plugin should claim a file:
4//! 1. File size > 100 MB
5//! 2. Compatible GPU available
6//! 3. Shannon entropy ≤ 7.5 bits/byte
7//!
8//! If all three pass, score = 0.95 (high priority for GPU).
9//! If any fails, score = 0.0 (decline — let another plugin handle it).
10
11use crate::entropy::ENTROPY_THRESHOLD;
12
13/// Minimum file size in bytes for GPU eligibility (100 MB).
14pub const MIN_FILE_SIZE: u64 = 100 * 1024 * 1024;
15
16/// Score assigned when all eligibility criteria pass.
17pub const ELIGIBLE_SCORE: f64 = 0.95;
18
19/// Input data for the eligibility scorer.
20#[derive(Debug, Clone)]
21pub struct EligibilityInput {
22 /// File size in bytes.
23 pub file_size: u64,
24 /// Whether a compatible GPU was discovered.
25 pub gpu_available: bool,
26 /// Shannon entropy of the file header sample (bits/byte).
27 pub entropy: f64,
28}
29
30/// Result of the eligibility evaluation.
31#[derive(Debug, Clone)]
32pub struct EligibilityResult {
33 /// Overall eligibility score (0.0 or 0.95).
34 pub score: f64,
35 /// Whether the file size criterion passed.
36 pub file_size_ok: bool,
37 /// Whether a compatible GPU was found.
38 pub gpu_ok: bool,
39 /// Whether the entropy criterion passed.
40 pub entropy_ok: bool,
41}
42
43impl EligibilityResult {
44 /// Evaluate eligibility from the given input.
45 #[must_use]
46 pub fn evaluate(input: &EligibilityInput) -> Self {
47 let file_size_ok = input.file_size > MIN_FILE_SIZE;
48 let gpu_ok = input.gpu_available;
49 let entropy_ok = input.entropy <= ENTROPY_THRESHOLD;
50
51 let score = if file_size_ok && gpu_ok && entropy_ok {
52 ELIGIBLE_SCORE
53 } else {
54 0.0
55 };
56
57 Self {
58 score,
59 file_size_ok,
60 gpu_ok,
61 entropy_ok,
62 }
63 }
64}