summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2020-02-03 21:25:19 +0100
committerCanop <cano.petrole@gmail.com>2020-02-03 21:25:19 +0100
commit8c945f5cc133e72b6c4fad1f69c202cf74eefbed (patch)
treecbd884729bbb8bf819a10c48ac752029e36216ff
parent78c4df297466a58812093ee43a5d270065746c1e (diff)
much faster :git_status
All git statuses are itered at once in order to avoid calling the libgit2 library several times (those calls are very costly)
-rw-r--r--src/browser_states.rs4
-rw-r--r--src/git_status.rs36
-rw-r--r--src/tree_build/builder.rs12
3 files changed, 26 insertions, 26 deletions
diff --git a/src/browser_states.rs b/src/browser_states.rs
index 00414ec..1181ee3 100644
--- a/src/browser_states.rs
+++ b/src/browser_states.rs
@@ -218,10 +218,6 @@ fn make_opener(
impl AppState for BrowserState {
fn has_pending_task(&self) -> bool {
- debug!(
- "CHECK self.displayed_tree().is_missing_git_status_computation() = {}",
- self.displayed_tree().is_missing_git_status_computation(),
- );
self.pending_pattern.is_some()
|| self.displayed_tree().has_dir_missing_size()
|| self.displayed_tree().is_missing_git_status_computation()
diff --git a/src/git_status.rs b/src/git_status.rs
index 7da51d1..ecfa7d4 100644
--- a/src/git_status.rs
+++ b/src/git_status.rs
@@ -6,7 +6,7 @@ use {
Status,
},
std::{
- collections::HashSet,
+ collections::HashMap,
path::{
Path,
PathBuf,
@@ -37,31 +37,35 @@ impl LineGitStatus {
}
pub struct LineStatusComputer {
- repo: Repository,
- repo_path: PathBuf,
- //interesting_paths: HashSet<PathBuf>,
+ interesting_statuses: HashMap<PathBuf, Status>,
}
impl LineStatusComputer {
pub fn from(repo: Repository) -> Self {
+ let repo_path = repo.path().parent().unwrap().to_path_buf();
+ let mut interesting_statuses = HashMap::new();
+ if let Ok(statuses) = &repo.statuses(None) {
+ for entry in statuses.iter() {
+ let status = entry.status();
+ if status.intersects(INTERESTING) {
+ if let Some(path) = entry.path() {
+ let path = repo_path.join(path);
+ interesting_statuses.insert(path, status);
+ }
+ }
+ }
+ } else {
+ debug!("get statuses failed");
+ }
Self {
- repo_path: repo.path().parent().unwrap().to_path_buf(),
- repo,
- //interesting_paths: HashSet::new(),
+ interesting_statuses,
}
}
pub fn line_status(&self, path: &Path) -> Option<LineGitStatus> {
- pathdiff::diff_paths(path, &self.repo_path)
- .and_then(|relative_path| LineGitStatus::from(&self.repo, &relative_path))
+ self.interesting_statuses.get(path).map(|&status| LineGitStatus { status })
}
pub fn is_interesting(&self, path: &Path) -> bool {
- match self.line_status(path) {
- Some(lgs) => lgs.is_interesting(),
- None => false,
- }
+ self.interesting_statuses.contains_key(path)
}
- //pub fn load_interesting_paths(&mut self) {
-
- //}
}
diff --git a/src/tree_build/builder.rs b/src/tree_build/builder.rs
index 84f1448..b071fc2 100644
--- a/src/tree_build/builder.rs
+++ b/src/tree_build/builder.rs
@@ -74,7 +74,11 @@ impl TreeBuilder {
let mut git_ignorer = time!(Debug, "GitIgnorer::new", GitIgnorer::new());
let root_ignore_chain = git_ignorer.root_chain(&path);
let line_status_computer = if options.filter_by_git_status || options.show_git_file_info {
- Repository::discover(&path).ok().map(LineStatusComputer::from)
+ time!(
+ Debug,
+ "init line_status_computer",
+ Repository::discover(&path).ok().map(LineStatusComputer::from),
+ )
} else {
None
};
@@ -420,11 +424,7 @@ impl TreeBuilder {
// it would make no sense to keep only files having a git status and
// not display that type
for mut line in tree.lines.iter_mut() {
- line.git_status = time!(
- Debug,
- "LineGitStatus",
- computer.line_status(&line.path),
- );
+ line.git_status = computer.line_status(&line.path);
}
}
tree