forked from mirrors/jj
op_walk: extract walk_ancestors() to new module
I'm going to extract fake "opset" resolution functions there, and I think walk_ancestors() belongs to the same category.
This commit is contained in:
parent
6dd936f72f
commit
94fc32ab47
4 changed files with 58 additions and 36 deletions
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use jj_lib::backend::ObjectId;
|
use jj_lib::backend::ObjectId;
|
||||||
use jj_lib::operation;
|
use jj_lib::op_walk;
|
||||||
use jj_lib::repo::Repo;
|
use jj_lib::repo::Repo;
|
||||||
|
|
||||||
use crate::cli_util::{user_error, CommandError, CommandHelper, LogContentFormat};
|
use crate::cli_util::{user_error, CommandError, CommandHelper, LogContentFormat};
|
||||||
|
@ -125,7 +125,7 @@ fn cmd_op_log(
|
||||||
ui.request_pager();
|
ui.request_pager();
|
||||||
let mut formatter = ui.stdout_formatter();
|
let mut formatter = ui.stdout_formatter();
|
||||||
let formatter = formatter.as_mut();
|
let formatter = formatter.as_mut();
|
||||||
let iter = operation::walk_ancestors(&head_op).take(args.limit.unwrap_or(usize::MAX));
|
let iter = op_walk::walk_ancestors(&head_op).take(args.limit.unwrap_or(usize::MAX));
|
||||||
if !args.no_graph {
|
if !args.no_graph {
|
||||||
let mut graph = get_graphlog(command.settings(), formatter.raw());
|
let mut graph = get_graphlog(command.settings(), formatter.raw());
|
||||||
let default_node_symbol = graph.default_node_symbol().to_owned();
|
let default_node_symbol = graph.default_node_symbol().to_owned();
|
||||||
|
|
|
@ -49,6 +49,7 @@ pub mod merge;
|
||||||
pub mod merged_tree;
|
pub mod merged_tree;
|
||||||
pub mod op_heads_store;
|
pub mod op_heads_store;
|
||||||
pub mod op_store;
|
pub mod op_store;
|
||||||
|
pub mod op_walk;
|
||||||
pub mod operation;
|
pub mod operation;
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod protos;
|
pub mod protos;
|
||||||
|
|
54
lib/src/op_walk.rs
Normal file
54
lib/src/op_walk.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2020-2023 The Jujutsu Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! Utility for operation id resolution and traversal.
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use itertools::Itertools as _;
|
||||||
|
|
||||||
|
use crate::dag_walk;
|
||||||
|
use crate::op_store::OpStoreResult;
|
||||||
|
use crate::operation::Operation;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
|
struct OperationByEndTime(Operation);
|
||||||
|
|
||||||
|
impl Ord for OperationByEndTime {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let self_end_time = &self.0.store_operation().metadata.end_time;
|
||||||
|
let other_end_time = &other.0.store_operation().metadata.end_time;
|
||||||
|
self_end_time
|
||||||
|
.cmp(other_end_time)
|
||||||
|
.then_with(|| self.0.cmp(&other.0)) // to comply with Eq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for OperationByEndTime {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Walks `head_op` and its ancestors in reverse topological order.
|
||||||
|
pub fn walk_ancestors(head_op: &Operation) -> impl Iterator<Item = OpStoreResult<Operation>> {
|
||||||
|
// Lazily load operations based on timestamp-based heuristic. This works so long
|
||||||
|
// as the operation history is mostly linear.
|
||||||
|
dag_walk::topo_order_reverse_lazy_ok(
|
||||||
|
[Ok(OperationByEndTime(head_op.clone()))],
|
||||||
|
|OperationByEndTime(op)| op.id().clone(),
|
||||||
|
|OperationByEndTime(op)| op.parents().map_ok(OperationByEndTime).collect_vec(),
|
||||||
|
)
|
||||||
|
.map_ok(|OperationByEndTime(op)| op)
|
||||||
|
}
|
|
@ -20,11 +20,9 @@ use std::fmt::{Debug, Error, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use itertools::Itertools as _;
|
|
||||||
|
|
||||||
use crate::backend::CommitId;
|
use crate::backend::CommitId;
|
||||||
|
use crate::op_store;
|
||||||
use crate::op_store::{OpStore, OpStoreResult, OperationId, ViewId};
|
use crate::op_store::{OpStore, OpStoreResult, OperationId, ViewId};
|
||||||
use crate::{dag_walk, op_store};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Operation {
|
pub struct Operation {
|
||||||
|
@ -165,34 +163,3 @@ impl View {
|
||||||
&self.data.head_ids
|
&self.data.head_ids
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
||||||
struct OperationByEndTime(Operation);
|
|
||||||
|
|
||||||
impl Ord for OperationByEndTime {
|
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
|
||||||
let self_end_time = &self.0.store_operation().metadata.end_time;
|
|
||||||
let other_end_time = &other.0.store_operation().metadata.end_time;
|
|
||||||
self_end_time
|
|
||||||
.cmp(other_end_time)
|
|
||||||
.then_with(|| self.0.cmp(&other.0)) // to comply with Eq
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for OperationByEndTime {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walks `head_op` and its ancestors in reverse topological order.
|
|
||||||
pub fn walk_ancestors(head_op: &Operation) -> impl Iterator<Item = OpStoreResult<Operation>> {
|
|
||||||
// Lazily load operations based on timestamp-based heuristic. This works so long
|
|
||||||
// as the operation history is mostly linear.
|
|
||||||
dag_walk::topo_order_reverse_lazy_ok(
|
|
||||||
[Ok(OperationByEndTime(head_op.clone()))],
|
|
||||||
|OperationByEndTime(op)| op.id().clone(),
|
|
||||||
|OperationByEndTime(op)| op.parents().map_ok(OperationByEndTime).collect_vec(),
|
|
||||||
)
|
|
||||||
.map_ok(|OperationByEndTime(op)| op)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue