From bce652eccaaf0f10aa9e391574b87d03054bc101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20R=C3=BC=C3=9Fler?= Date: Sun, 20 Jun 2021 19:29:18 +0200 Subject: [PATCH] Add filter to AsyncLog This is a small change that makes it possible to reuse the logic in `AsyncLog` for the file history view. `AsyncLog` passes the filter to `FileLogWalker` unchanged. --- asyncgit/src/revlog.rs | 16 +++++++++++++--- asyncgit/src/sync/logwalker.rs | 18 +++++++++--------- asyncgit/src/sync/mod.rs | 2 +- src/tabs/revlog.rs | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index e13c5895..aa4445b6 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -1,6 +1,6 @@ use crate::{ error::Result, - sync::{utils::repo, CommitId, LogWalker}, + sync::{utils::repo, CommitId, LogWalker, LogWalkerFilter}, AsyncGitNotification, CWD, }; use crossbeam_channel::Sender; @@ -32,6 +32,7 @@ pub struct AsyncLog { sender: Sender, pending: Arc, background: Arc, + filter: Option, } static LIMIT_COUNT: usize = 3000; @@ -40,12 +41,16 @@ static SLEEP_BACKGROUND: Duration = Duration::from_millis(1000); impl AsyncLog { /// - pub fn new(sender: &Sender) -> Self { + pub fn new( + sender: &Sender, + filter: Option, + ) -> Self { Self { current: Arc::new(Mutex::new(Vec::new())), sender: sender.clone(), pending: Arc::new(AtomicBool::new(false)), background: Arc::new(AtomicBool::new(false)), + filter, } } @@ -126,6 +131,8 @@ impl AsyncLog { self.pending.store(true, Ordering::Relaxed); + let filter = self.filter.clone(); + rayon_core::spawn(move || { scope_time!("async::revlog"); @@ -133,6 +140,7 @@ impl AsyncLog { &arc_current, &arc_background, &sender, + filter, ) .expect("failed to fetch"); @@ -148,10 +156,12 @@ impl AsyncLog { arc_current: &Arc>>, arc_background: &Arc, sender: &Sender, + filter: Option, ) -> Result<()> { let mut entries = Vec::with_capacity(LIMIT_COUNT); let r = repo(CWD)?; - let mut walker = LogWalker::new(&r, LIMIT_COUNT)?; + let mut walker = + LogWalker::new(&r, LIMIT_COUNT)?.filter(filter); loop { entries.clear(); let res_is_err = walker.read(&mut entries).is_err(); diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 56186f6f..b5caf946 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -4,6 +4,7 @@ use git2::{Commit, Oid, Repository}; use std::{ cmp::Ordering, collections::{BinaryHeap, HashSet}, + sync::Arc, }; struct TimeOrderedCommit<'a>(Commit<'a>); @@ -28,8 +29,10 @@ impl<'a> Ord for TimeOrderedCommit<'a> { } } -type LogWalkerFilter = - Box Result>; +/// +pub type LogWalkerFilter = Arc< + Box Result + Send + Sync>, +>; /// pub struct LogWalker<'a> { @@ -58,11 +61,8 @@ impl<'a> LogWalker<'a> { } /// - pub fn filter(self, filter: LogWalkerFilter) -> Self { - Self { - filter: Some(filter), - ..self - } + pub fn filter(self, filter: Option) -> Self { + Self { filter, ..self } } /// @@ -211,7 +211,7 @@ mod tests { let mut items = Vec::new(); let mut walker = LogWalker::new(&repo, 100)? - .filter(Box::new(diff_contains_baz)); + .filter(Some(Arc::new(Box::new(diff_contains_baz)))); walker.read(&mut items).unwrap(); assert_eq!(items.len(), 1); @@ -238,7 +238,7 @@ mod tests { let mut items = Vec::new(); let mut walker = LogWalker::new(&repo, 100)? - .filter(Box::new(diff_contains_bar)); + .filter(Some(Arc::new(Box::new(diff_contains_bar)))); walker.read(&mut items).unwrap(); assert_eq!(items.len(), 0); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 4cb4671f..851d45b6 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -55,7 +55,7 @@ pub use hooks::{ }; pub use hunks::{reset_hunk, stage_hunk, unstage_hunk}; pub use ignore::add_to_ignore; -pub use logwalker::LogWalker; +pub use logwalker::{LogWalker, LogWalkerFilter}; pub use merge::{ abort_merge, merge_branch, merge_commit, merge_msg, mergehead_ids, }; diff --git a/src/tabs/revlog.rs b/src/tabs/revlog.rs index 35779265..7a52a4a7 100644 --- a/src/tabs/revlog.rs +++ b/src/tabs/revlog.rs @@ -60,7 +60,7 @@ impl Revlog { theme, key_config.clone(), ), - git_log: AsyncLog::new(sender), + git_log: AsyncLog::new(sender, None), git_tags: AsyncTags::new(sender), visible: false, branch_name: cached::BranchName::new(CWD),