annotate rust/chg/src/main.rs @ 48178:f12a19d03d2c

fix: reduce number of tool executions By grouping together (path, ctx) pairs according to the inputs they would provide to fixer tools, we can deduplicate executions of fixer tools to significantly reduce the amount of time spent running slow tools. This change does not handle clean files in the working copy, which could still be deduplicated against the files in the checked out commit. It's a little harder to do that because the filerev is not available in the workingfilectx (and it doesn't exist for added files). Anecdotally, this change makes some real uses cases at Google 10x faster. I think we were originally hesitant to do this because the benefits weren't obvious, and implementing it efficiently is kind of tricky. If we simply memoized the formatter execution function, we would be keeping tons of file content in memory. Also included is a regression test for a corner case that I broke with my first attempt at optimizing this code. Differential Revision: https://phab.mercurial-scm.org/D11280
author Danny Hooper <hooper@google.com>
date Thu, 02 Sep 2021 14:08:45 -0700
parents 4b0185841058
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 // Copyright 2018 Yuya Nishihara <yuya@tcha.org>
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 //
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
6 use chg::locator::{self, Locator};
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39979
diff changeset
7 use chg::procutil;
44754
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
8 use chg::ChgUiHandler;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
9 use std::env;
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
10 use std::io;
44754
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
11 use std::io::Write;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
12 use std::process;
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
13 use std::time::Instant;
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
14
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
15 struct DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
16 start: Instant,
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
17 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
18
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
19 impl DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
20 pub fn new() -> DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
21 DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
22 start: Instant::now(),
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
23 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
24 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
25 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
26
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
27 impl log::Log for DebugLogger {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
28 fn enabled(&self, metadata: &log::Metadata) -> bool {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
29 metadata.target().starts_with("chg::")
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
30 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
31
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
32 fn log(&self, record: &log::Record) {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
33 if self.enabled(record.metadata()) {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
34 // just make the output looks similar to chg of C
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
35 let l = format!("{}", record.level()).to_lowercase();
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
36 let t = self.start.elapsed();
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
37 writeln!(
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
38 io::stderr(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
39 "chg: {}: {}.{:06} {}",
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
40 l,
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
41 t.as_secs(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
42 t.subsec_micros(),
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
43 record.args()
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
44 )
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
45 .unwrap_or(());
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
46 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
47 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
48
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40288
diff changeset
49 fn flush(&self) {}
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
50 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
51
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
52 fn main() {
40288
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
53 if env::var_os("CHGDEBUG").is_some() {
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
54 log::set_boxed_logger(Box::new(DebugLogger::new()))
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
55 .expect("any logger should not be installed yet");
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
56 log::set_max_level(log::LevelFilter::Debug);
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
57 }
87c76e5f3427 rust-chg: install logger if $CHGDEBUG is set
Yuya Nishihara <yuya@tcha.org>
parents: 40286
diff changeset
58
44671
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
59 // TODO: add loop detection by $CHGINTERNALMARK
bb936e25a84a rust-chg: spawn server process if not running
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
60
44694
5ac5c25ea97b rust-chg: move get_umask() call out of run() function
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
61 let umask = unsafe { procutil::get_umask() }; // not thread safe
5ac5c25ea97b rust-chg: move get_umask() call out of run() function
Yuya Nishihara <yuya@tcha.org>
parents: 44688
diff changeset
62 let code = run(umask).unwrap_or_else(|err| {
40286
af52181f71ff rust-chg: suppress panic while writing chg error to stderr
Yuya Nishihara <yuya@tcha.org>
parents: 40120
diff changeset
63 writeln!(io::stderr(), "chg: abort: {}", err).unwrap_or(());
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
64 255
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
65 });
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
66 process::exit(code);
39967
aab43d5861bb rust-chg: add project skeleton
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
67 }
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
68
44754
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
69 #[tokio::main]
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
70 async fn run(umask: u32) -> io::Result<i32> {
44681
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
71 let mut loc = Locator::prepare_from_env()?;
00ac60658654 rust-chg: collect server flags from command arguments
Yuya Nishihara <yuya@tcha.org>
parents: 44673
diff changeset
72 loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
44754
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
73 let mut handler = ChgUiHandler::new();
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
74 let mut client = loc.connect().await?;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
75 client
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
76 .attach_io(&io::stdin(), &io::stdout(), &io::stderr())
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
77 .await?;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
78 client.set_umask(umask).await?;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
79 let pid = client.server_spec().process_id.unwrap();
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
80 let pgid = client.server_spec().process_group_id;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
81 procutil::setup_signal_handler_once(pid, pgid)?;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
82 let code = client
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
83 .run_command_chg(&mut handler, env::args_os().skip(1))
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
84 .await?;
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
85 procutil::restore_signal_handler_once()?;
44755
4b0185841058 rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents: 44754
diff changeset
86 handler.wait_pager().await?;
44754
9fc9526e283a rust-chg: modernize entry function
Yuya Nishihara <yuya@tcha.org>
parents: 44694
diff changeset
87 Ok(code)
39979
6bdee4bc181a rust-chg: add main program
Yuya Nishihara <yuya@tcha.org>
parents: 39967
diff changeset
88 }