Skip to content

Commit 31e3799

Browse files
authored
Split up main (#39)
Moved code from inside the main function into function calls
1 parent f3b1dd0 commit 31e3799

File tree

2 files changed

+90
-43
lines changed

2 files changed

+90
-43
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
**/*.rs.bk
33
*.data
44
*.old
5+
out.sql

src/main.rs

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,19 @@ impl FromStr for LevelSizes {
9292
}
9393
}
9494

95-
fn main() {
96-
#[allow(deprecated)]
97-
let matches = App::new(crate_name!())
95+
struct Config {
96+
db_url: String,
97+
output_file: Option<File>,
98+
room_id: String,
99+
max_state_group: Option<i64>,
100+
min_saved_rows: Option<i32>,
101+
transactions: bool,
102+
level_sizes: LevelSizes,
103+
}
104+
105+
impl Config {
106+
fn parse_arguments() -> Config {
107+
let matches = App::new(crate_name!())
98108
.version(crate_version!())
99109
.author(crate_authors!("\n"))
100110
.about(crate_description!())
@@ -156,33 +166,50 @@ fn main() {
156166
.takes_value(true),
157167
).get_matches();
158168

159-
let db_url = matches
160-
.value_of("postgres-url")
161-
.expect("db url should be required");
169+
let db_url = matches
170+
.value_of("postgres-url")
171+
.expect("db url should be required");
172+
173+
let output_file = matches
174+
.value_of("output_file")
175+
.map(|path| File::create(path).unwrap());
162176

163-
let mut output_file = matches
164-
.value_of("output_file")
165-
.map(|path| File::create(path).unwrap());
177+
let room_id = matches
178+
.value_of("room_id")
179+
.expect("room_id should be required since no file");
166180

167-
let room_id = matches
168-
.value_of("room_id")
169-
.expect("room_id should be required since no file");
181+
let max_state_group = matches
182+
.value_of("max_state_group")
183+
.map(|s| s.parse().expect("max_state_group must be an integer"));
170184

171-
let max_state_group = matches
172-
.value_of("max_state_group")
173-
.map(|s| s.parse().expect("max_state_group must be an integer"));
185+
let min_saved_rows = matches
186+
.value_of("min_saved_rows")
187+
.map(|v| v.parse().expect("COUNT must be an integer"));
174188

175-
let min_saved_rows = matches
176-
.value_of("min_saved_rows")
177-
.map(|v| v.parse().expect("COUNT must be an integer"));
189+
let transactions = matches.is_present("transactions");
178190

179-
let transactions = matches.is_present("transactions");
191+
let level_sizes = value_t_or_exit!(matches, "level_sizes", LevelSizes);
180192

181-
let level_sizes = value_t_or_exit!(matches, "level_sizes", LevelSizes);
193+
Config {
194+
db_url: String::from(db_url),
195+
output_file,
196+
room_id: String::from(room_id),
197+
max_state_group,
198+
min_saved_rows,
199+
transactions,
200+
level_sizes,
201+
}
202+
}
203+
}
204+
205+
fn main() {
206+
let mut config = Config::parse_arguments();
182207

183208
// First we need to get the current state groups
184-
println!("Fetching state from DB for room '{}'...", room_id);
185-
let state_group_map = database::get_data_from_db(db_url, room_id, max_state_group);
209+
println!("Fetching state from DB for room '{}'...", config.room_id);
210+
211+
let state_group_map =
212+
database::get_data_from_db(&config.db_url, &config.room_id, config.max_state_group);
186213

187214
println!("Number of state groups: {}", state_group_map.len());
188215

@@ -196,7 +223,7 @@ fn main() {
196223

197224
println!("Compressing state...");
198225

199-
let compressor = Compressor::compress(&state_group_map, &level_sizes.0);
226+
let compressor = Compressor::compress(&state_group_map, &config.level_sizes.0);
200227

201228
let new_state_group_map = compressor.new_state_group_map;
202229

@@ -228,7 +255,7 @@ fn main() {
228255
compressor.stats.state_groups_changed
229256
);
230257

231-
if let Some(min) = min_saved_rows {
258+
if let Some(min) = config.min_saved_rows {
232259
let saving = (original_summed_size - compressed_summed_size) as i32;
233260
if saving < min {
234261
println!(
@@ -239,25 +266,39 @@ fn main() {
239266
}
240267
}
241268

269+
check_that_maps_match(&state_group_map, &new_state_group_map);
270+
242271
// If we are given an output file, we output the changes as SQL. If the
243272
// `transactions` argument is set we wrap each change to a state group in a
244273
// transaction.
245274

246-
if let Some(output) = &mut output_file {
247-
println!("Writing changes...");
275+
output_sql(&mut config, &state_group_map, &new_state_group_map);
276+
}
248277

249-
let pb = ProgressBar::new(state_group_map.len() as u64);
250-
pb.set_style(
251-
ProgressStyle::default_bar().template("[{elapsed_precise}] {bar} {pos}/{len} {msg}"),
252-
);
253-
pb.set_message("state groups");
254-
pb.enable_steady_tick(100);
278+
fn output_sql(
279+
config: &mut Config,
280+
old_map: &BTreeMap<i64, StateGroupEntry>,
281+
new_map: &BTreeMap<i64, StateGroupEntry>,
282+
) {
283+
if config.output_file.is_none() {
284+
return;
285+
}
286+
287+
println!("Writing changes...");
288+
289+
let pb = ProgressBar::new(old_map.len() as u64);
290+
pb.set_style(
291+
ProgressStyle::default_bar().template("[{elapsed_precise}] {bar} {pos}/{len} {msg}"),
292+
);
293+
pb.set_message("state groups");
294+
pb.enable_steady_tick(100);
255295

256-
for (sg, old_entry) in &state_group_map {
257-
let new_entry = &new_state_group_map[sg];
296+
if let Some(output) = &mut config.output_file {
297+
for (sg, old_entry) in old_map {
298+
let new_entry = &new_map[sg];
258299

259300
if old_entry != new_entry {
260-
if transactions {
301+
if config.transactions {
261302
writeln!(output, "BEGIN;").unwrap();
262303
}
263304

@@ -292,7 +333,7 @@ fn main() {
292333
output,
293334
"({}, {}, {}, {}, {})",
294335
sg,
295-
PGEscape(room_id),
336+
PGEscape(&config.room_id),
296337
PGEscape(t),
297338
PGEscape(s),
298339
PGEscape(e)
@@ -302,21 +343,26 @@ fn main() {
302343
writeln!(output, ";").unwrap();
303344
}
304345

305-
if transactions {
346+
if config.transactions {
306347
writeln!(output, "COMMIT;").unwrap();
307348
}
308349
writeln!(output).unwrap();
309350
}
310351

311352
pb.inc(1);
312353
}
313-
314-
pb.finish();
315354
}
316355

356+
pb.finish();
357+
}
358+
359+
fn check_that_maps_match(
360+
old_map: &BTreeMap<i64, StateGroupEntry>,
361+
new_map: &BTreeMap<i64, StateGroupEntry>,
362+
) {
317363
println!("Checking that state maps match...");
318364

319-
let pb = ProgressBar::new(state_group_map.len() as u64);
365+
let pb = ProgressBar::new(old_map.len() as u64);
320366
pb.set_style(
321367
ProgressStyle::default_bar().template("[{elapsed_precise}] {bar} {pos}/{len} {msg}"),
322368
);
@@ -325,11 +371,11 @@ fn main() {
325371

326372
// Now let's iterate through and assert that the state for each group
327373
// matches between the two versions.
328-
state_group_map
374+
old_map
329375
.par_iter() // This uses rayon to run the checks in parallel
330376
.try_for_each(|(sg, _)| {
331-
let expected = collapse_state_maps(&state_group_map, *sg);
332-
let actual = collapse_state_maps(&new_state_group_map, *sg);
377+
let expected = collapse_state_maps(&old_map, *sg);
378+
let actual = collapse_state_maps(&new_map, *sg);
333379

334380
pb.inc(1);
335381

0 commit comments

Comments
 (0)