view: extract function for updating operation heads

This will be used to address the race in `Transaction::commit()`.
This commit is contained in:
Martin von Zweigbergk 2021-03-10 14:43:40 -08:00
parent fc73ef8d6e
commit 47a7cf7101
2 changed files with 16 additions and 10 deletions

View file

@ -73,6 +73,10 @@ impl Operation {
&self.id &self.id
} }
pub fn parent_ids(&self) -> &Vec<OperationId> {
&self.data.parents
}
pub fn parents(&self) -> Vec<Operation> { pub fn parents(&self) -> Vec<Operation> {
let mut parents = Vec::new(); let mut parents = Vec::new();
for parent_id in &self.data.parents { for parent_id in &self.data.parents {

View file

@ -568,8 +568,6 @@ impl MutableView {
} }
pub fn save(self, description: String, operation_start_time: Timestamp) -> Operation { 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 view_id = self.op_store.write_view(&self.data).unwrap();
let mut operation_metadata = OperationMetadata::new(description); let mut operation_metadata = OperationMetadata::new(description);
operation_metadata.start_time = operation_start_time; operation_metadata.start_time = operation_start_time;
@ -578,16 +576,20 @@ impl MutableView {
parents: vec![self.base_op_head_id.clone()], parents: vec![self.base_op_head_id.clone()],
metadata: operation_metadata, 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 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/. 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")); let _op_heads_lock = FileLock::lock(op_heads_dir.join("lock"));
add_op_head(&op_heads_dir, &new_op_head_id); add_op_head(&op_heads_dir, op.id());
remove_op_head(&op_heads_dir, &old_op_head_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)
} }
} }