Skip to main content

paper_client/
policy.rs

1/*
2 * Copyright (c) Kia Shakiba
3 *
4 * This source code is licensed under the GNU AGPLv3 license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8use std::{
9	fmt::{self, Display},
10	str::FromStr,
11};
12
13use crate::error::PaperClientError;
14
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub enum PaperPolicy {
17	Auto,
18	Lfu,
19	Fifo,
20	Clock,
21	Sieve,
22	Lru,
23	Mru,
24	TwoQ(f64, f64),
25	Arc,
26	SThreeFifo(f64),
27}
28
29impl Display for PaperPolicy {
30	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31		match self {
32			PaperPolicy::Auto => write!(f, "auto"),
33			PaperPolicy::Lfu => write!(f, "lfu"),
34			PaperPolicy::Fifo => write!(f, "fifo"),
35			PaperPolicy::Clock => write!(f, "clock"),
36			PaperPolicy::Sieve => write!(f, "sieve"),
37			PaperPolicy::Lru => write!(f, "lru"),
38			PaperPolicy::Mru => write!(f, "mru"),
39			PaperPolicy::TwoQ(k_in, k_out) => write!(f, "2q-{k_in}-{k_out}"),
40			PaperPolicy::Arc => write!(f, "arc"),
41			PaperPolicy::SThreeFifo(ratio) => write!(f, "s3-fifo-{ratio}"),
42		}
43	}
44}
45
46impl FromStr for PaperPolicy {
47	type Err = PaperClientError;
48
49	fn from_str(value: &str) -> Result<Self, Self::Err> {
50		let policy = match value {
51			"auto" => PaperPolicy::Auto,
52			"lfu" => PaperPolicy::Lfu,
53			"fifo" => PaperPolicy::Fifo,
54			"clock" => PaperPolicy::Clock,
55			"sieve" => PaperPolicy::Sieve,
56			"lru" => PaperPolicy::Lru,
57			"mru" => PaperPolicy::Mru,
58			value if value.starts_with("2q-") => parse_two_q(value)?,
59			"arc" => PaperPolicy::Arc,
60			value if value.starts_with("s3-fifo-") => parse_s_three_fifo(value)?,
61
62			_ => return Err(PaperClientError::Internal),
63		};
64
65		Ok(policy)
66	}
67}
68
69fn parse_two_q(value: &str) -> Result<PaperPolicy, PaperClientError> {
70	// skip the "2q-"
71	let tokens = value[3..].split('-').collect::<Vec<&str>>();
72
73	if tokens.len() != 2 {
74		return Err(PaperClientError::Internal);
75	}
76
77	let Ok(k_in) = tokens[0].parse::<f64>() else {
78		return Err(PaperClientError::Internal);
79	};
80
81	let Ok(k_out) = tokens[1].parse::<f64>() else {
82		return Err(PaperClientError::Internal);
83	};
84
85	Ok(PaperPolicy::TwoQ(k_in, k_out))
86}
87
88fn parse_s_three_fifo(value: &str) -> Result<PaperPolicy, PaperClientError> {
89	// skip the "s3-fifo-"
90	let tokens = value[8..].split('-').collect::<Vec<&str>>();
91
92	if tokens.len() != 1 {
93		return Err(PaperClientError::Internal);
94	}
95
96	let Ok(ratio) = tokens[0].parse::<f64>() else {
97		return Err(PaperClientError::Internal);
98	};
99
100	Ok(PaperPolicy::SThreeFifo(ratio))
101}