1#![forbid(unsafe_code)]
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Strategy {
6 Fast,
8 DFast,
10}
11
12#[derive(Debug, Clone, Copy)]
17pub struct LevelParams {
18 pub strategy: Strategy,
19 pub window_log: u32,
20 pub hash_log: u32,
21 pub chain_log: u32,
23 pub search_log: u32,
24 pub min_match: u32,
25 pub target_length: u32,
26 pub search_strength: u32,
27 pub force_raw_literals: bool,
28}
29
30pub const DEFAULT_LEVEL: i32 = 1;
32
33pub fn level_params(level: i32) -> Option<LevelParams> {
38 level_params_for_size(level, usize::MAX)
39}
40
41pub fn level_params_for_size(level: i32, src_len: usize) -> Option<LevelParams> {
47 let mut params = level_params_inner(level)?;
48 if (2..usize::MAX).contains(&src_len) {
49 let src_log = 32 - ((src_len as u32) - 1).leading_zeros();
50 params.hash_log = params.hash_log.min(src_log);
51 params.chain_log = params.chain_log.min(src_log);
52 params.window_log = params.window_log.min(src_log);
53 }
54 Some(params)
55}
56
57pub fn max_hash_log(level: i32) -> Option<u32> {
60 let p = level_params_inner(level)?;
61 Some(p.hash_log.max(p.chain_log))
62}
63
64fn level_params_inner(level: i32) -> Option<LevelParams> {
65 Some(match level {
66 0 => return level_params_inner(DEFAULT_LEVEL),
67 -7 => LevelParams {
68 strategy: Strategy::Fast,
69 window_log: 19,
70 hash_log: 13,
71 chain_log: 13,
72 search_log: 0,
73 min_match: 5,
74 target_length: 7,
75 search_strength: 7,
76 force_raw_literals: true,
77 },
78 -6 => LevelParams {
79 strategy: Strategy::Fast,
80 window_log: 19,
81 hash_log: 13,
82 chain_log: 13,
83 search_log: 0,
84 min_match: 5,
85 target_length: 7,
86 search_strength: 7,
87 force_raw_literals: false,
88 },
89 -5 => LevelParams {
90 strategy: Strategy::Fast,
91 window_log: 19,
92 hash_log: 13,
93 chain_log: 13,
94 search_log: 0,
95 min_match: 5,
96 target_length: 6,
97 search_strength: 7,
98 force_raw_literals: false,
99 },
100 -4 => LevelParams {
101 strategy: Strategy::Fast,
102 window_log: 19,
103 hash_log: 13,
104 chain_log: 13,
105 search_log: 0,
106 min_match: 5,
107 target_length: 5,
108 search_strength: 7,
109 force_raw_literals: false,
110 },
111 -3 => LevelParams {
112 strategy: Strategy::Fast,
113 window_log: 19,
114 hash_log: 13,
115 chain_log: 13,
116 search_log: 0,
117 min_match: 5,
118 target_length: 4,
119 search_strength: 7,
120 force_raw_literals: false,
121 },
122 -2 => LevelParams {
123 strategy: Strategy::Fast,
124 window_log: 19,
125 hash_log: 13,
126 chain_log: 13,
127 search_log: 0,
128 min_match: 5,
129 target_length: 3,
130 search_strength: 7,
131 force_raw_literals: false,
132 },
133 -1 => LevelParams {
134 strategy: Strategy::Fast,
135 window_log: 19,
136 hash_log: 13,
137 chain_log: 13,
138 search_log: 0,
139 min_match: 5,
140 target_length: 2,
141 search_strength: 7,
142 force_raw_literals: false,
143 },
144 1 => LevelParams {
145 strategy: Strategy::Fast,
146 window_log: 19,
147 hash_log: 14,
148 chain_log: 14,
149 search_log: 0,
150 min_match: 4,
151 target_length: 1,
152 search_strength: 8,
153 force_raw_literals: false,
154 },
155 2 => LevelParams {
156 strategy: Strategy::Fast,
157 window_log: 20,
158 hash_log: 16,
159 chain_log: 16,
160 search_log: 0,
161 min_match: 4,
162 target_length: 1,
163 search_strength: 8,
164 force_raw_literals: false,
165 },
166 3 => LevelParams {
167 strategy: Strategy::DFast,
168 window_log: 21,
169 hash_log: 18,
170 chain_log: 18,
171 search_log: 1,
172 min_match: 4,
173 target_length: 1,
174 search_strength: 5,
175 force_raw_literals: false,
176 },
177 4 => LevelParams {
178 strategy: Strategy::DFast,
179 window_log: 23,
180 hash_log: 19,
181 chain_log: 19,
182 search_log: 1,
183 min_match: 4,
184 target_length: 1,
185 search_strength: 6,
186 force_raw_literals: false,
187 },
188 _ => return None,
189 })
190}