mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-27 06:27:43 +00:00
revset: move ReverseRevsetGraphIterator
into revset
module
The iterator is not specific to the implementation in `revset_graph_iterator`, so it belongs in the standard `revset` module.
This commit is contained in:
parent
f62fac24ac
commit
3871efd2f9
5 changed files with 112 additions and 112 deletions
|
@ -1488,6 +1488,49 @@ pub struct RevsetWorkspaceContext<'a> {
|
|||
pub workspace_root: &'a Path,
|
||||
}
|
||||
|
||||
pub struct ReverseRevsetGraphIterator<'index> {
|
||||
items: Vec<(IndexEntry<'index>, Vec<RevsetGraphEdge>)>,
|
||||
}
|
||||
|
||||
impl<'index> ReverseRevsetGraphIterator<'index> {
|
||||
pub fn new<'revset>(
|
||||
input: Box<dyn Iterator<Item = (IndexEntry<'index>, Vec<RevsetGraphEdge>)> + 'revset>,
|
||||
) -> Self {
|
||||
let mut entries = vec![];
|
||||
let mut reverse_edges: HashMap<IndexPosition, Vec<RevsetGraphEdge>> = HashMap::new();
|
||||
for (entry, edges) in input {
|
||||
for RevsetGraphEdge { target, edge_type } in edges {
|
||||
reverse_edges
|
||||
.entry(target)
|
||||
.or_default()
|
||||
.push(RevsetGraphEdge {
|
||||
target: entry.position(),
|
||||
edge_type,
|
||||
})
|
||||
}
|
||||
entries.push(entry);
|
||||
}
|
||||
|
||||
let mut items = vec![];
|
||||
for entry in entries.into_iter() {
|
||||
let edges = reverse_edges
|
||||
.get(&entry.position())
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
items.push((entry, edges));
|
||||
}
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'index> Iterator for ReverseRevsetGraphIterator<'index> {
|
||||
type Item = (IndexEntry<'index>, Vec<RevsetGraphEdge>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.items.pop()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
use std::cmp::min;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use crate::default_index_store::{IndexEntry, IndexPosition};
|
||||
use crate::nightly_shims::BTreeMapExt;
|
||||
|
@ -270,46 +270,3 @@ impl<'revset, 'index> Iterator for RevsetGraphIterator<'revset, 'index> {
|
|||
Some((index_entry, edges))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReverseRevsetGraphIterator<'index> {
|
||||
items: Vec<(IndexEntry<'index>, Vec<RevsetGraphEdge>)>,
|
||||
}
|
||||
|
||||
impl<'index> ReverseRevsetGraphIterator<'index> {
|
||||
pub fn new<'revset>(
|
||||
input: Box<dyn Iterator<Item = (IndexEntry<'index>, Vec<RevsetGraphEdge>)> + 'revset>,
|
||||
) -> Self {
|
||||
let mut entries = vec![];
|
||||
let mut reverse_edges: HashMap<IndexPosition, Vec<RevsetGraphEdge>> = HashMap::new();
|
||||
for (entry, edges) in input {
|
||||
for RevsetGraphEdge { target, edge_type } in edges {
|
||||
reverse_edges
|
||||
.entry(target)
|
||||
.or_default()
|
||||
.push(RevsetGraphEdge {
|
||||
target: entry.position(),
|
||||
edge_type,
|
||||
})
|
||||
}
|
||||
entries.push(entry);
|
||||
}
|
||||
|
||||
let mut items = vec![];
|
||||
for entry in entries.into_iter() {
|
||||
let edges = reverse_edges
|
||||
.get(&entry.position())
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
items.push((entry, edges));
|
||||
}
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'index> Iterator for ReverseRevsetGraphIterator<'index> {
|
||||
type Item = (IndexEntry<'index>, Vec<RevsetGraphEdge>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.items.pop()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,15 +15,16 @@
|
|||
use std::path::Path;
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use itertools::Itertools;
|
||||
use jujutsu_lib::backend::{CommitId, MillisSinceEpoch, ObjectId, Signature, Timestamp};
|
||||
use jujutsu_lib::default_revset_engine::resolve_symbol;
|
||||
use jujutsu_lib::default_revset_engine::{resolve_symbol, revset_for_commits};
|
||||
use jujutsu_lib::git;
|
||||
use jujutsu_lib::op_store::{RefTarget, WorkspaceId};
|
||||
use jujutsu_lib::repo::Repo;
|
||||
use jujutsu_lib::repo_path::RepoPath;
|
||||
use jujutsu_lib::revset::{
|
||||
optimize, parse, RevsetAliasesMap, RevsetError, RevsetExpression, RevsetFilterPredicate,
|
||||
RevsetIteratorExt, RevsetWorkspaceContext,
|
||||
optimize, parse, ReverseRevsetGraphIterator, RevsetAliasesMap, RevsetError, RevsetExpression,
|
||||
RevsetFilterPredicate, RevsetGraphEdge, RevsetIteratorExt, RevsetWorkspaceContext,
|
||||
};
|
||||
use jujutsu_lib::settings::GitSettings;
|
||||
use jujutsu_lib::workspace::Workspace;
|
||||
|
@ -2011,3 +2012,64 @@ fn test_evaluate_expression_file(use_git: bool) {
|
|||
vec![commit4.id().clone()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse_graph_iterator() {
|
||||
let settings = testutils::user_settings();
|
||||
let test_repo = TestRepo::init(true);
|
||||
let repo = &test_repo.repo;
|
||||
|
||||
// Tests that merges, forks, direct edges, indirect edges, and "missing" edges
|
||||
// are correct in reversed graph. "Missing" edges (i.e. edges to commits not
|
||||
// in the input set) won't be part of the reversed graph. Conversely, there
|
||||
// won't be missing edges to children not in the input.
|
||||
//
|
||||
// F
|
||||
// |\
|
||||
// D E
|
||||
// |/
|
||||
// C
|
||||
// |
|
||||
// b
|
||||
// |
|
||||
// A
|
||||
// |
|
||||
// root
|
||||
let mut tx = repo.start_transaction(&settings, "test");
|
||||
let mut graph_builder = CommitGraphBuilder::new(&settings, tx.mut_repo());
|
||||
let commit_a = graph_builder.initial_commit();
|
||||
let commit_b = graph_builder.commit_with_parents(&[&commit_a]);
|
||||
let commit_c = graph_builder.commit_with_parents(&[&commit_b]);
|
||||
let commit_d = graph_builder.commit_with_parents(&[&commit_c]);
|
||||
let commit_e = graph_builder.commit_with_parents(&[&commit_c]);
|
||||
let commit_f = graph_builder.commit_with_parents(&[&commit_d, &commit_e]);
|
||||
let repo = tx.commit();
|
||||
|
||||
let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap();
|
||||
let pos_d = repo.index().commit_id_to_pos(commit_d.id()).unwrap();
|
||||
let pos_e = repo.index().commit_id_to_pos(commit_e.id()).unwrap();
|
||||
let pos_f = repo.index().commit_id_to_pos(commit_f.id()).unwrap();
|
||||
|
||||
let revset = revset_for_commits(
|
||||
&repo,
|
||||
&[&commit_a, &commit_c, &commit_d, &commit_e, &commit_f],
|
||||
);
|
||||
let commits = ReverseRevsetGraphIterator::new(revset.iter_graph()).collect_vec();
|
||||
assert_eq!(commits.len(), 5);
|
||||
assert_eq!(commits[0].0.commit_id(), *commit_a.id());
|
||||
assert_eq!(commits[1].0.commit_id(), *commit_c.id());
|
||||
assert_eq!(commits[2].0.commit_id(), *commit_d.id());
|
||||
assert_eq!(commits[3].0.commit_id(), *commit_e.id());
|
||||
assert_eq!(commits[4].0.commit_id(), *commit_f.id());
|
||||
assert_eq!(commits[0].1, vec![RevsetGraphEdge::indirect(pos_c)]);
|
||||
assert_eq!(
|
||||
commits[1].1,
|
||||
vec![
|
||||
RevsetGraphEdge::direct(pos_e),
|
||||
RevsetGraphEdge::direct(pos_d),
|
||||
]
|
||||
);
|
||||
assert_eq!(commits[2].1, vec![RevsetGraphEdge::direct(pos_f)]);
|
||||
assert_eq!(commits[3].1, vec![RevsetGraphEdge::direct(pos_f)]);
|
||||
assert_eq!(commits[4].1, vec![]);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use itertools::Itertools;
|
|||
use jujutsu_lib::default_revset_engine::revset_for_commits;
|
||||
use jujutsu_lib::repo::Repo;
|
||||
use jujutsu_lib::revset::RevsetGraphEdge;
|
||||
use jujutsu_lib::revset_graph_iterator::{ReverseRevsetGraphIterator, RevsetGraphIterator};
|
||||
use jujutsu_lib::revset_graph_iterator::RevsetGraphIterator;
|
||||
use test_case::test_case;
|
||||
use testutils::{CommitGraphBuilder, TestRepo};
|
||||
|
||||
|
@ -367,64 +367,3 @@ fn test_graph_iterator_edge_escapes_from_(skip_transitive_edges: bool) {
|
|||
assert_eq!(commits[3].1, vec![RevsetGraphEdge::indirect(pos_a)]);
|
||||
assert_eq!(commits[4].1, vec![RevsetGraphEdge::missing(pos_root)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse_graph_iterator() {
|
||||
let settings = testutils::user_settings();
|
||||
let test_repo = TestRepo::init(true);
|
||||
let repo = &test_repo.repo;
|
||||
|
||||
// Tests that merges, forks, direct edges, indirect edges, and "missing" edges
|
||||
// are correct in reversed graph. "Missing" edges (i.e. edges to commits not
|
||||
// in the input set) won't be part of the reversed graph. Conversely, there
|
||||
// won't be missing edges to children not in the input.
|
||||
//
|
||||
// F
|
||||
// |\
|
||||
// D E
|
||||
// |/
|
||||
// C
|
||||
// |
|
||||
// b
|
||||
// |
|
||||
// A
|
||||
// |
|
||||
// root
|
||||
let mut tx = repo.start_transaction(&settings, "test");
|
||||
let mut graph_builder = CommitGraphBuilder::new(&settings, tx.mut_repo());
|
||||
let commit_a = graph_builder.initial_commit();
|
||||
let commit_b = graph_builder.commit_with_parents(&[&commit_a]);
|
||||
let commit_c = graph_builder.commit_with_parents(&[&commit_b]);
|
||||
let commit_d = graph_builder.commit_with_parents(&[&commit_c]);
|
||||
let commit_e = graph_builder.commit_with_parents(&[&commit_c]);
|
||||
let commit_f = graph_builder.commit_with_parents(&[&commit_d, &commit_e]);
|
||||
let repo = tx.commit();
|
||||
|
||||
let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap();
|
||||
let pos_d = repo.index().commit_id_to_pos(commit_d.id()).unwrap();
|
||||
let pos_e = repo.index().commit_id_to_pos(commit_e.id()).unwrap();
|
||||
let pos_f = repo.index().commit_id_to_pos(commit_f.id()).unwrap();
|
||||
|
||||
let revset = revset_for_commits(
|
||||
&repo,
|
||||
&[&commit_a, &commit_c, &commit_d, &commit_e, &commit_f],
|
||||
);
|
||||
let commits = ReverseRevsetGraphIterator::new(revset.iter_graph()).collect_vec();
|
||||
assert_eq!(commits.len(), 5);
|
||||
assert_eq!(commits[0].0.commit_id(), *commit_a.id());
|
||||
assert_eq!(commits[1].0.commit_id(), *commit_c.id());
|
||||
assert_eq!(commits[2].0.commit_id(), *commit_d.id());
|
||||
assert_eq!(commits[3].0.commit_id(), *commit_e.id());
|
||||
assert_eq!(commits[4].0.commit_id(), *commit_f.id());
|
||||
assert_eq!(commits[0].1, vec![RevsetGraphEdge::indirect(pos_c)]);
|
||||
assert_eq!(
|
||||
commits[1].1,
|
||||
vec![
|
||||
RevsetGraphEdge::direct(pos_e),
|
||||
RevsetGraphEdge::direct(pos_d),
|
||||
]
|
||||
);
|
||||
assert_eq!(commits[2].1, vec![RevsetGraphEdge::direct(pos_f)]);
|
||||
assert_eq!(commits[3].1, vec![RevsetGraphEdge::direct(pos_f)]);
|
||||
assert_eq!(commits[4].1, vec![]);
|
||||
}
|
||||
|
|
|
@ -36,10 +36,9 @@ use jujutsu_lib::op_store::{RefTarget, WorkspaceId};
|
|||
use jujutsu_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujutsu_lib::repo_path::RepoPath;
|
||||
use jujutsu_lib::revset::{
|
||||
RevsetAliasesMap, RevsetExpression, RevsetFilterPredicate, RevsetGraphEdge,
|
||||
RevsetGraphEdgeType, RevsetIteratorExt,
|
||||
ReverseRevsetGraphIterator, RevsetAliasesMap, RevsetExpression, RevsetFilterPredicate,
|
||||
RevsetGraphEdge, RevsetGraphEdgeType, RevsetIteratorExt,
|
||||
};
|
||||
use jujutsu_lib::revset_graph_iterator::ReverseRevsetGraphIterator;
|
||||
use jujutsu_lib::rewrite::{back_out_commit, merge_commit_trees, rebase_commit, DescendantRebaser};
|
||||
use jujutsu_lib::settings::UserSettings;
|
||||
use jujutsu_lib::tree::{merge_trees, Tree};
|
||||
|
|
Loading…
Reference in a new issue