From 47a7cf71017330123015179664958651217e4561 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Wed, 10 Mar 2021 14:43:40 -0800 Subject: [PATCH] view: extract function for updating operation heads This will be used to address the race in `Transaction::commit()`. --- lib/src/operation.rs | 4 ++++ lib/src/view.rs | 22 ++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/src/operation.rs b/lib/src/operation.rs index 96e998ed0..9e0cb7905 100644 --- a/lib/src/operation.rs +++ b/lib/src/operation.rs @@ -73,6 +73,10 @@ impl Operation { &self.id } + pub fn parent_ids(&self) -> &Vec { + &self.data.parents + } + pub fn parents(&self) -> Vec { let mut parents = Vec::new(); for parent_id in &self.data.parents { diff --git a/lib/src/view.rs b/lib/src/view.rs index 182707762..078cae4fa 100644 --- a/lib/src/view.rs +++ b/lib/src/view.rs @@ -568,8 +568,6 @@ impl MutableView { } pub fn save(self, description: String, operation_start_time: Timestamp) -> Operation { - let op_heads_dir = self.path.join("op_heads"); - let view_id = self.op_store.write_view(&self.data).unwrap(); let mut operation_metadata = OperationMetadata::new(description); operation_metadata.start_time = operation_start_time; @@ -578,16 +576,20 @@ impl MutableView { parents: vec![self.base_op_head_id.clone()], metadata: operation_metadata, }; - let old_op_head_id = self.base_op_head_id.clone(); let new_op_head_id = self.op_store.write_operation(&operation).unwrap(); + let operation = Operation::new(self.op_store.clone(), new_op_head_id, operation); - // Update .jj/view/op_heads/. - { - let _op_heads_lock = FileLock::lock(op_heads_dir.join("lock")); - add_op_head(&op_heads_dir, &new_op_head_id); - remove_op_head(&op_heads_dir, &old_op_head_id); + self.update_op_heads(&operation); + + operation + } + + pub fn update_op_heads(&self, op: &Operation) { + let op_heads_dir = self.path.join("op_heads"); + let _op_heads_lock = FileLock::lock(op_heads_dir.join("lock")); + add_op_head(&op_heads_dir, op.id()); + for old_parent_id in op.parent_ids() { + remove_op_head(&op_heads_dir, old_parent_id); } - - Operation::new(self.op_store, new_op_head_id, operation) } }