mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-15 12:14:27 +00:00
view: use the Operation wrapper type in merge_op_heads()
This is partly to prepare for merging the operations in order of transaction-commit time (currently merged in order of operation id), so we can get a predictable order in tests (assuming transactions are not committed the same millisecond).
This commit is contained in:
parent
48e664c716
commit
c4cd12e93e
@ -214,45 +214,55 @@ fn get_single_op_head(
|
|||||||
fn merge_op_heads(
|
fn merge_op_heads(
|
||||||
store: &StoreWrapper,
|
store: &StoreWrapper,
|
||||||
op_store: &Arc<dyn OpStore>,
|
op_store: &Arc<dyn OpStore>,
|
||||||
op_heads: &[OperationId],
|
op_head_ids: &[OperationId],
|
||||||
) -> Result<(OperationId, op_store::Operation, op_store::View), OpHeadResolutionError> {
|
) -> Result<(OperationId, op_store::Operation, op_store::View), OpHeadResolutionError> {
|
||||||
let neighbors_fn = |op_id: &OperationId| op_store.read_operation(op_id).unwrap().parents;
|
let op_heads: Vec<_> = op_head_ids
|
||||||
|
.iter()
|
||||||
|
.map(|op_id: &OperationId| {
|
||||||
|
let data = op_store.read_operation(op_id).unwrap();
|
||||||
|
Operation::new(op_store.clone(), op_id.clone(), data)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let neighbors_fn = |op: &Operation| op.parents();
|
||||||
// Remove ancestors so we don't create merge operation with an operation and its
|
// Remove ancestors so we don't create merge operation with an operation and its
|
||||||
// ancestor
|
// ancestor
|
||||||
let op_heads = dag_walk::unreachable(
|
let op_heads =
|
||||||
op_heads.iter().cloned(),
|
dag_walk::unreachable(op_heads, &neighbors_fn, &|op: &Operation| op.id().clone());
|
||||||
&neighbors_fn,
|
|
||||||
&|op_id: &OperationId| op_id.clone(),
|
|
||||||
);
|
|
||||||
let mut op_heads: Vec<_> = op_heads.into_iter().collect();
|
let mut op_heads: Vec<_> = op_heads.into_iter().collect();
|
||||||
op_heads.sort_by_key(|op_id| op_id.0.clone());
|
op_heads.sort_by_key(|op| op.id().0.clone());
|
||||||
let first_op_head = op_store.read_operation(&op_heads[0]).unwrap();
|
let first_op_head = op_heads[0].clone();
|
||||||
let mut merged_view = op_store.read_view(&first_op_head.view_id).unwrap();
|
let mut merged_view = op_store.read_view(first_op_head.view().id()).unwrap();
|
||||||
|
|
||||||
// Return without creating a merge operation
|
// Return without creating a merge operation
|
||||||
if op_heads.len() == 1 {
|
if op_heads.len() == 1 {
|
||||||
return Ok((op_heads[0].clone(), first_op_head, merged_view));
|
return Ok((
|
||||||
|
op_heads[0].id().clone(),
|
||||||
|
first_op_head.store_operation().clone(),
|
||||||
|
merged_view,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, other_op_head_id) in op_heads.iter().enumerate().skip(1) {
|
for (i, other_op_head) in op_heads.iter().enumerate().skip(1) {
|
||||||
let ancestor_op_id = dag_walk::closest_common_node(
|
let ancestor_op = dag_walk::closest_common_node(
|
||||||
op_heads[0..i].to_vec(),
|
op_heads[0..i].to_vec(),
|
||||||
vec![other_op_head_id.clone()],
|
vec![other_op_head.clone()],
|
||||||
&neighbors_fn,
|
&neighbors_fn,
|
||||||
&|op_id: &OperationId| op_id.clone(),
|
&|op: &Operation| op.id().clone(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let ancestor_op = op_store.read_operation(&ancestor_op_id).unwrap();
|
merged_view = merge_views(
|
||||||
let ancestor_view = op_store.read_view(&ancestor_op.view_id).unwrap();
|
store,
|
||||||
let other_op = op_store.read_operation(other_op_head_id).unwrap();
|
&merged_view,
|
||||||
let other_view = op_store.read_view(&other_op.view_id).unwrap();
|
ancestor_op.view().store_view(),
|
||||||
merged_view = merge_views(store, &merged_view, &ancestor_view, &other_view);
|
other_op_head.view().store_view(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let merged_view_id = op_store.write_view(&merged_view).unwrap();
|
let merged_view_id = op_store.write_view(&merged_view).unwrap();
|
||||||
let operation_metadata = OperationMetadata::new("resolve concurrent operations".to_string());
|
let operation_metadata = OperationMetadata::new("resolve concurrent operations".to_string());
|
||||||
|
let op_parent_ids = op_heads.iter().map(|op| op.id().clone()).collect();
|
||||||
let merge_operation = op_store::Operation {
|
let merge_operation = op_store::Operation {
|
||||||
view_id: merged_view_id,
|
view_id: merged_view_id,
|
||||||
parents: op_heads,
|
parents: op_parent_ids,
|
||||||
metadata: operation_metadata,
|
metadata: operation_metadata,
|
||||||
};
|
};
|
||||||
let merge_operation_id = op_store.write_operation(&merge_operation).unwrap();
|
let merge_operation_id = op_store.write_operation(&merge_operation).unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user