ok/jj
1
0
Fork 0
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:
Yuya Nishihara 2023-12-31 10:21:47 +09:00
parent 6dd936f72f
commit 94fc32ab47
4 changed files with 58 additions and 36 deletions

View file

@ -14,7 +14,7 @@
use clap::Subcommand;
use jj_lib::backend::ObjectId;
use jj_lib::operation;
use jj_lib::op_walk;
use jj_lib::repo::Repo;
use crate::cli_util::{user_error, CommandError, CommandHelper, LogContentFormat};
@ -125,7 +125,7 @@ fn cmd_op_log(
ui.request_pager();
let mut formatter = ui.stdout_formatter();
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 {
let mut graph = get_graphlog(command.settings(), formatter.raw());
let default_node_symbol = graph.default_node_symbol().to_owned();

View file

@ -49,6 +49,7 @@ pub mod merge;
pub mod merged_tree;
pub mod op_heads_store;
pub mod op_store;
pub mod op_walk;
pub mod operation;
#[allow(missing_docs)]
pub mod protos;

54
lib/src/op_walk.rs Normal file
View 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)
}

View file

@ -20,11 +20,9 @@ use std::fmt::{Debug, Error, Formatter};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
use itertools::Itertools as _;
use crate::backend::CommitId;
use crate::op_store;
use crate::op_store::{OpStore, OpStoreResult, OperationId, ViewId};
use crate::{dag_walk, op_store};
#[derive(Clone)]
pub struct Operation {
@ -165,34 +163,3 @@ impl View {
&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)
}