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.
This commit is contained in:
Christoph Rüßler 2021-06-20 19:29:18 +02:00 committed by Stephan Dilly
parent 7f0a23681a
commit bce652ecca
4 changed files with 24 additions and 14 deletions

View file

@ -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<AsyncGitNotification>,
pending: Arc<AtomicBool>,
background: Arc<AtomicBool>,
filter: Option<LogWalkerFilter>,
}
static LIMIT_COUNT: usize = 3000;
@ -40,12 +41,16 @@ static SLEEP_BACKGROUND: Duration = Duration::from_millis(1000);
impl AsyncLog {
///
pub fn new(sender: &Sender<AsyncGitNotification>) -> Self {
pub fn new(
sender: &Sender<AsyncGitNotification>,
filter: Option<LogWalkerFilter>,
) -> 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<Mutex<Vec<CommitId>>>,
arc_background: &Arc<AtomicBool>,
sender: &Sender<AsyncGitNotification>,
filter: Option<LogWalkerFilter>,
) -> 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();

View file

@ -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<dyn Fn(&Repository, &CommitId) -> Result<bool>>;
///
pub type LogWalkerFilter = Arc<
Box<dyn Fn(&Repository, &CommitId) -> Result<bool> + 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<LogWalkerFilter>) -> 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);

View file

@ -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,
};

View file

@ -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),