mirror of
https://github.com/gitui-org/gitui
synced 2026-05-22 16:38:28 +00:00
parent
ebe41e8a75
commit
52dfefe624
6 changed files with 34 additions and 86 deletions
|
|
@ -11,9 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
* fix commit log not updating after branch switch ([#1862](https://github.com/extrawurst/gitui/issues/1862))
|
||||
* fix stashlist not updating after pop/drop ([#1864](https://github.com/extrawurst/gitui/issues/1864))
|
||||
|
||||
### Changed
|
||||
* log search consumes all cores now and got even faster
|
||||
|
||||
## [0.24.1] - 2023-08-30
|
||||
|
||||
### Fixes
|
||||
|
|
|
|||
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -61,7 +61,6 @@ dependencies = [
|
|||
"log",
|
||||
"openssl-sys",
|
||||
"pretty_assertions",
|
||||
"rayon",
|
||||
"rayon-core",
|
||||
"scopetime",
|
||||
"serde",
|
||||
|
|
@ -1259,16 +1258,6 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.11.0"
|
||||
|
|
|
|||
1
Makefile
1
Makefile
|
|
@ -2,7 +2,6 @@
|
|||
.PHONY: debug build-release release-linux-musl test clippy clippy-pedantic install install-debug
|
||||
|
||||
ARGS=-l
|
||||
# ARGS=-l -d ~/code/extern/kubernetes
|
||||
# ARGS=-l -d ~/code/extern/linux
|
||||
# ARGS=-l -d ~/code/git-bare-test.git -w ~/code/git-bare-test
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ log = "0.4"
|
|||
# git2 = { git="https://github.com/extrawurst/git2-rs.git", rev="fc13dcc", features = ["vendored-openssl"]}
|
||||
# pinning to vendored openssl, using the git2 feature this gets lost with new resolver
|
||||
openssl-sys = { version = '0.9', features = ["vendored"], optional = true }
|
||||
rayon = "1.7"
|
||||
rayon-core = "1.11"
|
||||
scopetime = { path = "../scopetime", version = "0.1" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
|||
|
|
@ -7,17 +7,12 @@ use crossbeam_channel::Sender;
|
|||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
/// Passed to `AsyncJob::run` allowing sending intermediate progress notifications
|
||||
pub struct RunParams<
|
||||
T: Copy + Send,
|
||||
P: Clone + Send + Sync + PartialEq,
|
||||
> {
|
||||
pub struct RunParams<T: Copy + Send, P: Clone + Send + Sync> {
|
||||
sender: Sender<T>,
|
||||
progress: Arc<RwLock<P>>,
|
||||
}
|
||||
|
||||
impl<T: Copy + Send, P: Clone + Send + Sync + PartialEq>
|
||||
RunParams<T, P>
|
||||
{
|
||||
impl<T: Copy + Send, P: Clone + Send + Sync> RunParams<T, P> {
|
||||
/// send an intermediate update notification.
|
||||
/// do not confuse this with the return value of `run`.
|
||||
/// `send` should only be used about progress notifications
|
||||
|
|
@ -29,13 +24,9 @@ impl<T: Copy + Send, P: Clone + Send + Sync + PartialEq>
|
|||
}
|
||||
|
||||
/// set the current progress
|
||||
pub fn set_progress(&self, p: P) -> Result<bool> {
|
||||
Ok(if *self.progress.read()? == p {
|
||||
false
|
||||
} else {
|
||||
*(self.progress.write()?) = p;
|
||||
true
|
||||
})
|
||||
pub fn set_progress(&self, p: P) -> Result<()> {
|
||||
*(self.progress.write()?) = p;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +35,7 @@ pub trait AsyncJob: Send + Sync + Clone {
|
|||
/// defines what notification type is used to communicate outside
|
||||
type Notification: Copy + Send;
|
||||
/// type of progress
|
||||
type Progress: Clone + Default + Send + Sync + PartialEq;
|
||||
type Progress: Clone + Default + Send + Sync;
|
||||
|
||||
/// can run a synchronous time intensive task.
|
||||
/// the returned notification is used to tell interested parties
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
use rayon::{
|
||||
prelude::ParallelIterator,
|
||||
slice::{ParallelSlice, ParallelSliceMut},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
asyncjob::{AsyncJob, RunParams},
|
||||
error::Result,
|
||||
|
|
@ -10,7 +5,7 @@ use crate::{
|
|||
AsyncGitNotification, ProgressPercent,
|
||||
};
|
||||
use std::{
|
||||
sync::{atomic::AtomicUsize, Arc, Mutex},
|
||||
sync::{Arc, Mutex},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
|
|
@ -74,63 +69,45 @@ impl AsyncCommitFilterJob {
|
|||
commits: Vec<CommitId>,
|
||||
params: &RunParams<AsyncGitNotification, ProgressPercent>,
|
||||
) -> JobState {
|
||||
let (start, result) =
|
||||
self.filter_commits(repo_path, commits, params);
|
||||
let response = sync::repo(repo_path)
|
||||
.map(|repo| self.filter_commits(&repo, commits, params))
|
||||
.map(|(start, result)| CommitFilterResult {
|
||||
result,
|
||||
duration: start.elapsed(),
|
||||
});
|
||||
|
||||
//TODO: still need this to be a result?
|
||||
JobState::Response(Ok(CommitFilterResult {
|
||||
result,
|
||||
duration: start.elapsed(),
|
||||
}))
|
||||
JobState::Response(response)
|
||||
}
|
||||
|
||||
fn filter_commits(
|
||||
&self,
|
||||
repo_path: &RepoPath,
|
||||
repo: &git2::Repository,
|
||||
commits: Vec<CommitId>,
|
||||
params: &RunParams<AsyncGitNotification, ProgressPercent>,
|
||||
) -> (Instant, Vec<CommitId>) {
|
||||
let total_amount = commits.len();
|
||||
let start = Instant::now();
|
||||
|
||||
let idx = AtomicUsize::new(0);
|
||||
let mut result = commits
|
||||
let mut progress = ProgressPercent::new(0, total_amount);
|
||||
|
||||
let result = commits
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.collect::<Vec<(usize, CommitId)>>()
|
||||
.par_chunks(1000)
|
||||
.filter_map(|c| {
|
||||
//TODO: error log repo open errors
|
||||
sync::repo(repo_path).ok().map(|repo| {
|
||||
c.iter()
|
||||
.filter_map(|(e, c)| {
|
||||
let idx = idx.fetch_add(
|
||||
1,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
.filter_map(|(idx, c)| {
|
||||
let new_progress =
|
||||
ProgressPercent::new(idx, total_amount);
|
||||
|
||||
Self::update_progress(
|
||||
params,
|
||||
ProgressPercent::new(
|
||||
idx,
|
||||
total_amount,
|
||||
),
|
||||
);
|
||||
if new_progress != progress {
|
||||
Self::update_progress(params, new_progress);
|
||||
progress = new_progress;
|
||||
}
|
||||
|
||||
(*self.filter)(&repo, c).ok().and_then(
|
||||
|res| res.then_some((*e, *c)),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
(*self.filter)(repo, &c)
|
||||
.ok()
|
||||
.and_then(|res| res.then_some(c))
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
result.par_sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
let result = result.into_iter().map(|c| c.1).collect();
|
||||
|
||||
(start, result)
|
||||
}
|
||||
|
||||
|
|
@ -138,16 +115,12 @@ impl AsyncCommitFilterJob {
|
|||
params: &RunParams<AsyncGitNotification, ProgressPercent>,
|
||||
new_progress: ProgressPercent,
|
||||
) {
|
||||
match params.set_progress(new_progress) {
|
||||
Err(e) => log::error!("progress error: {e}"),
|
||||
Ok(result) if result => {
|
||||
if let Err(e) =
|
||||
params.send(AsyncGitNotification::CommitFilter)
|
||||
{
|
||||
log::error!("send error: {e}");
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
if let Err(e) = params.set_progress(new_progress) {
|
||||
log::error!("progress error: {e}");
|
||||
} else if let Err(e) =
|
||||
params.send(AsyncGitNotification::CommitFilter)
|
||||
{
|
||||
log::error!("send error: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue