Skip to content

Commit 6006e7a

Browse files
author
Stephan Dilly
committed
use new custom logwalker
1 parent e8c2dc2 commit 6006e7a

File tree

4 files changed

+63
-85
lines changed

4 files changed

+63
-85
lines changed

asyncgit/src/revlog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl AsyncLog {
151151
) -> Result<()> {
152152
let mut entries = Vec::with_capacity(LIMIT_COUNT);
153153
let r = repo(CWD)?;
154-
let mut walker = LogWalker::new(&r, LIMIT_COUNT);
154+
let mut walker = LogWalker::new(&r, LIMIT_COUNT)?;
155155
loop {
156156
entries.clear();
157157
let res_is_err = walker.read(&mut entries).is_err();

asyncgit/src/sync/commit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ mod tests {
126126

127127
fn count_commits(repo: &Repository, max: usize) -> usize {
128128
let mut items = Vec::new();
129-
let mut walk = LogWalker::new(&repo, max);
129+
let mut walk = LogWalker::new(&repo, max).unwrap();
130130
walk.read(&mut items).unwrap();
131131
items.len()
132132
}

asyncgit/src/sync/logwalker.rs

Lines changed: 57 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,82 @@
1-
#![allow(clippy::missing_panics_doc)]
2-
31
use super::CommitId;
42
use crate::error::Result;
5-
use git2::{Repository, Revwalk};
3+
use git2::{Commit, Oid, Repository};
4+
use std::{
5+
cmp::Ordering,
6+
collections::{BinaryHeap, HashSet},
7+
};
8+
9+
struct TimeOrderedCommit<'a>(Commit<'a>);
10+
11+
impl<'a> Eq for TimeOrderedCommit<'a> {}
12+
13+
impl<'a> PartialEq for TimeOrderedCommit<'a> {
14+
fn eq(&self, other: &Self) -> bool {
15+
self.0.time().eq(&other.0.time())
16+
}
17+
}
18+
19+
impl<'a> PartialOrd for TimeOrderedCommit<'a> {
20+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
21+
self.0.time().partial_cmp(&other.0.time())
22+
}
23+
}
24+
25+
impl<'a> Ord for TimeOrderedCommit<'a> {
26+
fn cmp(&self, other: &Self) -> Ordering {
27+
self.0.time().cmp(&other.0.time())
28+
}
29+
}
630

731
///
832
pub struct LogWalker<'a> {
9-
repo: &'a Repository,
10-
revwalk: Option<Revwalk<'a>>,
33+
commits: BinaryHeap<TimeOrderedCommit<'a>>,
34+
visited: HashSet<Oid>,
1135
limit: usize,
1236
}
1337

1438
impl<'a> LogWalker<'a> {
1539
///
16-
pub const fn new(repo: &'a Repository, limit: usize) -> Self {
17-
Self {
18-
repo,
19-
revwalk: None,
40+
pub fn new(repo: &'a Repository, limit: usize) -> Result<Self> {
41+
let c = repo.head()?.peel_to_commit()?;
42+
43+
let mut commits = BinaryHeap::with_capacity(10);
44+
commits.push(TimeOrderedCommit(c));
45+
46+
Ok(Self {
47+
commits,
2048
limit,
21-
}
49+
visited: HashSet::with_capacity(1000),
50+
})
2251
}
2352

2453
///
2554
pub fn read(&mut self, out: &mut Vec<CommitId>) -> Result<usize> {
2655
let mut count = 0_usize;
2756

28-
if self.revwalk.is_none() {
29-
let mut walk = self.repo.revwalk()?;
30-
31-
walk.push_head()?;
32-
33-
self.revwalk = Some(walk);
34-
}
57+
while let Some(c) = self.commits.pop() {
58+
for p in c.0.parents() {
59+
self.visit(p);
60+
}
3561

36-
if let Some(ref mut walk) = self.revwalk {
37-
for id in walk.into_iter().flatten() {
38-
out.push(id.into());
39-
count += 1;
62+
out.push(c.0.id().into());
4063

41-
if count == self.limit {
42-
break;
43-
}
64+
count += 1;
65+
if count == self.limit {
66+
break;
4467
}
4568
}
4669

4770
Ok(count)
4871
}
72+
73+
//
74+
fn visit(&mut self, c: Commit<'a>) {
75+
if !self.visited.contains(&c.id()) {
76+
self.visited.insert(c.id());
77+
self.commits.push(TimeOrderedCommit(c));
78+
}
79+
}
4980
}
5081

5182
#[cfg(test)]
@@ -73,7 +104,7 @@ mod tests {
73104
let oid2 = commit(repo_path, "commit2").unwrap();
74105

75106
let mut items = Vec::new();
76-
let mut walk = LogWalker::new(&repo, 1);
107+
let mut walk = LogWalker::new(&repo, 1)?;
77108
walk.read(&mut items).unwrap();
78109

79110
assert_eq!(items.len(), 1);
@@ -97,7 +128,7 @@ mod tests {
97128
let oid2 = commit(repo_path, "commit2").unwrap();
98129

99130
let mut items = Vec::new();
100-
let mut walk = LogWalker::new(&repo, 100);
131+
let mut walk = LogWalker::new(&repo, 100)?;
101132
walk.read(&mut items).unwrap();
102133

103134
let info = get_commits_info(repo_path, &items, 50).unwrap();
@@ -113,60 +144,4 @@ mod tests {
113144

114145
Ok(())
115146
}
116-
117-
// fn walk_all_commits(repo: &Repository) -> Vec<CommitId> {
118-
// let mut items = Vec::new();
119-
// let mut walk = LogWalker::new(&repo).mode(Mode::AllRefs);
120-
// walk.read(&mut items, 10).unwrap();
121-
// items
122-
// }
123-
124-
// #[test]
125-
// fn test_multiple_branches() {
126-
// let (td, repo) = repo_init_empty().unwrap();
127-
// let repo_path = td.path().to_string_lossy();
128-
129-
// let c1 = write_commit_file_at(
130-
// &repo,
131-
// "test.txt",
132-
// "",
133-
// "c1",
134-
// Time::new(1, 0),
135-
// );
136-
137-
// let items = walk_all_commits(&repo);
138-
139-
// assert_eq!(items, vec![c1]);
140-
141-
// let b1 = create_branch(&repo_path, "b1").unwrap();
142-
143-
// let c2 = write_commit_file_at(
144-
// &repo,
145-
// "test2.txt",
146-
// "",
147-
// "c2",
148-
// Time::new(2, 0),
149-
// );
150-
151-
// let items = walk_all_commits(&repo);
152-
// assert_eq!(items, vec![c2, c1]);
153-
154-
// let _b2 = create_branch(&repo_path, "b2").unwrap();
155-
156-
// let c3 = write_commit_file_at(
157-
// &repo,
158-
// "test3.txt",
159-
// "",
160-
// "c3",
161-
// Time::new(3, 0),
162-
// );
163-
164-
// let items = walk_all_commits(&repo);
165-
// assert_eq!(items, vec![c2, c3, c1]);
166-
167-
// checkout_branch(&repo_path, &b1).unwrap();
168-
169-
// let items = walk_all_commits(&repo);
170-
// assert_eq!(items, vec![c2, c3, c1]);
171-
// }
172147
}

asyncgit/src/sync/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,10 @@ mod tests {
274274
max_count: usize,
275275
) -> Vec<CommitId> {
276276
let mut commit_ids = Vec::<CommitId>::new();
277-
LogWalker::new(r, max_count).read(&mut commit_ids).unwrap();
277+
LogWalker::new(r, max_count)
278+
.unwrap()
279+
.read(&mut commit_ids)
280+
.unwrap();
278281

279282
commit_ids
280283
}

0 commit comments

Comments
 (0)