Skip to content

Commit 09c4dc9

Browse files
Byrono2sh
andauthored
gix upgrade and optimizations (#1081)
* upgrade to latest gix v0.46 and make use of free traversal state. The latest improvements make more data available during commit iteration, which makes some improvements possible. Doing so potentially saves some time, even though it's not visible in practice. * change: bot commits now provide their commit time to first/most-recent commit information. In practice, this change is unlikely to be noticeable, especially since `--no-bots` is not enabled by default. However, if it is, bot commits will now contribute to the most recent commit times and the first commit times, which will help if the only commit is a bot commit. It also helps with allowing an upcoming multi-threaded implementation that leverages the commit-graph which in turn will greatly speed up information retrieval in large repositories. * refactor retrieval of commit graph information to make output clear This is in preparation for creating a multi-threaded version of it. * refactor retrieval of commit graph information to make output clear This is in preparation for creating a multi-threaded version of it. * refactoring - Extrat commit graph traversal logic out of CommitMetrics's constructor - renaming and simplified logic * minor * cargo fmt * remove is_shallow property from GitMetrics * Single thread for churn and author summary on main thread * process author sig in seperate thread * revert * refactor * unify logic to update number of commits by author. More notes related to the `use_commit_graph()` call: I was thinking about this API for a while, and it's the easiest way to configure this even though it seems redundant. Let me explain, maybe you can find a better solution. In an even more recent version, `use_commit_graph()` doesn't default to `true`, but defaults to the value of `core.commitGraph`, which in turn defaults to true. We, however, always want to use the commitgraph, under the condition that we can use enough threads *and* actually have a commit-graph. Now, one would think that `with_commit_graph` is enough to get what we want, but since `use_commit_graph` generally defaults to `true` under the hood it would make another attempt to open the commit-graph, even though there might not be one. This leads to the commit-graph detection to be run twice in the case there is none. Thus we explicitly set our verdict in `use_commit_graph` to avoid that kind of work. Does it matter, you might ask? Probably not on today's SSDs, a few `stat` calls don't matter, so if you want, you can remove the `use_commit_graph` call. By default, I want an API that allows to avoid any waste, which is why it's implemented that way. ---- More notes related to the overcommit of threads There isn't really a such a thing like exhausting threads, but indeed this implementation will overcommit a little bit for N threads: * N threads for author computation (author) * 1 thread for commit-iteration and author aggregation (aggregator) * 1 threads for churn computation (churn) The aggregator thread has to wait for (author) threads and won't be busy doing its work - thanks to the commit-graph these walks are very fast. It won't actually consume much CPU. The churn thread is the one that runs just as hot if not hotter than the author threads, and I intend to let these contend a little as typically a little bit of over-commit eeks out a little more performance in practice. This is due to IO still playing a role here and once a thread is blocked, it's good to have a choice of more threads to run. Further, the `churn` thread is operating on a best-effort basis so to me its fine to drown it out a little, if the OS decides to do that, but in turn it gets a little additional time while the author threads are joined, so it should even out. Fearless concurrency is fun :). * explicitly call use_commit_graph and with_commit_graph --------- Co-authored-by: o2sh <[email protected]>
1 parent fd1d5f0 commit 09c4dc9

File tree

15 files changed

+652
-484
lines changed

15 files changed

+652
-484
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ jobs:
5252
- name: Run onefetch
5353
run: cargo run
5454

55+
- name: Run onefetch (with commitgraph)
56+
run: git commit-graph write --no-progress --reachable && cargo run
57+
5558
formatting:
5659
runs-on: ubuntu-latest
5760
steps:

Cargo.lock

Lines changed: 50 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ byte-unit = "4.0.19"
2323
bytecount = "0.6.3"
2424
clap = { version = "4.3.1", features = ["derive"] }
2525
clap_complete = "4.3.1"
26-
gix-features-for-configuration-only = { package = "gix-features", version = "0.29.0", features = [
26+
crossbeam-channel = "0.5.8"
27+
gix-features-for-configuration-only = { package = "gix-features", version = "0.30.0", features = [
2728
"zlib-ng",
2829
] }
29-
gix = { version = "0.45.1", default-features = false, features = [
30+
gix = { version = "0.46.0", default-features = false, features = [
3031
"max-performance-safe",
3132
] }
3233
git2 = { version = "0.17.2", default-features = false }
@@ -49,6 +50,7 @@ time-humanize = { version = "0.1.3", features = ["time"] }
4950
tokei = "12.1.2"
5051
typetag = "0.2"
5152
yaml-rust = "0.4.5"
53+
parking_lot = "0.12"
5254

5355
[dev-dependencies]
5456
criterion = "0.4.0"

src/info/author.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use super::git::metrics::GitMetrics;
12
use crate::{
23
cli::NumberSeparator,
3-
info::{format_number, utils::git::CommitMetrics, utils::info_field::InfoField},
4+
info::{format_number, utils::info_field::InfoField},
45
};
56
use serde::Serialize;
67
use std::fmt::Write;
@@ -65,8 +66,8 @@ pub struct AuthorsInfo {
6566
}
6667

6768
impl AuthorsInfo {
68-
pub fn new(commit_metrics: &CommitMetrics) -> Self {
69-
let authors = commit_metrics.authors_to_display.clone();
69+
pub fn new(git_metrics: &GitMetrics) -> Self {
70+
let authors = git_metrics.authors_to_display.clone();
7071
Self { authors }
7172
}
7273
}

src/info/churn.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::utils::{git::CommitMetrics, info_field::InfoField};
1+
use super::{git::metrics::GitMetrics, utils::info_field::InfoField};
22
use crate::{cli::NumberSeparator, info::format_number};
33
use serde::Serialize;
44
use std::fmt::Write;
@@ -43,11 +43,11 @@ pub struct ChurnInfo {
4343
pub churn_pool_size: usize,
4444
}
4545
impl ChurnInfo {
46-
pub fn new(commit_metrics: &CommitMetrics) -> Self {
47-
let file_churns = commit_metrics.file_churns_to_display.clone();
46+
pub fn new(git_metrics: &GitMetrics) -> Self {
47+
let file_churns = git_metrics.file_churns_to_display.clone();
4848
Self {
4949
file_churns,
50-
churn_pool_size: commit_metrics.churn_pool_size,
50+
churn_pool_size: git_metrics.churn_pool_size,
5151
}
5252
}
5353
}

src/info/commits.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use serde::Serialize;
2-
1+
use super::git::metrics::GitMetrics;
32
use crate::{
43
cli::NumberSeparator,
5-
info::{format_number, utils::git::CommitMetrics, utils::info_field::InfoField},
4+
info::{format_number, utils::info_field::InfoField},
65
};
6+
use serde::Serialize;
77

88
#[derive(Serialize)]
99
#[serde(rename_all = "camelCase")]
@@ -15,10 +15,14 @@ pub struct CommitsInfo {
1515
}
1616

1717
impl CommitsInfo {
18-
pub fn new(commit_metrics: &CommitMetrics, number_separator: NumberSeparator) -> Self {
18+
pub fn new(
19+
git_metrics: &GitMetrics,
20+
is_shallow: bool,
21+
number_separator: NumberSeparator,
22+
) -> Self {
1923
Self {
20-
number_of_commits: commit_metrics.total_number_of_commits,
21-
is_shallow: commit_metrics.is_shallow,
24+
number_of_commits: git_metrics.total_number_of_commits,
25+
is_shallow,
2226
number_separator,
2327
}
2428
}

0 commit comments

Comments
 (0)