mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-16 00:56:23 +00:00
working_copy: use OnceCell for lazy instantiation of TreeState
Here OnceCell<T> serves as RefCell<Option<T>>, but it doesn't require runtime Ref/RefMut wrapper. This allows us to get rid of some .clone() calls needed to hide Ref<_> from public interface.
This commit is contained in:
parent
4f72ec142d
commit
786e6211d8
1 changed files with 16 additions and 20 deletions
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::cell::{Ref, RefCell, RefMut};
|
use std::cell::RefCell;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -27,6 +27,7 @@ use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::UNIX_EPOCH;
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
|
use once_cell::unsync::OnceCell;
|
||||||
use protobuf::{EnumOrUnknown, Message, MessageField};
|
use protobuf::{EnumOrUnknown, Message, MessageField};
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -963,7 +964,7 @@ pub struct WorkingCopy {
|
||||||
state_path: PathBuf,
|
state_path: PathBuf,
|
||||||
operation_id: RefCell<Option<OperationId>>,
|
operation_id: RefCell<Option<OperationId>>,
|
||||||
workspace_id: RefCell<Option<WorkspaceId>>,
|
workspace_id: RefCell<Option<WorkspaceId>>,
|
||||||
tree_state: RefCell<Option<TreeState>>,
|
tree_state: OnceCell<TreeState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkingCopy {
|
impl WorkingCopy {
|
||||||
|
@ -992,7 +993,7 @@ impl WorkingCopy {
|
||||||
state_path,
|
state_path,
|
||||||
operation_id: RefCell::new(Some(operation_id)),
|
operation_id: RefCell::new(Some(operation_id)),
|
||||||
workspace_id: RefCell::new(Some(workspace_id)),
|
workspace_id: RefCell::new(Some(workspace_id)),
|
||||||
tree_state: RefCell::new(None),
|
tree_state: OnceCell::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,7 +1004,7 @@ impl WorkingCopy {
|
||||||
state_path,
|
state_path,
|
||||||
operation_id: RefCell::new(None),
|
operation_id: RefCell::new(None),
|
||||||
workspace_id: RefCell::new(None),
|
workspace_id: RefCell::new(None),
|
||||||
tree_state: RefCell::new(None),
|
tree_state: OnceCell::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,24 +1056,19 @@ impl WorkingCopy {
|
||||||
self.workspace_id.borrow().as_ref().unwrap().clone()
|
self.workspace_id.borrow().as_ref().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_tree_state(&self) {
|
fn tree_state(&self) -> &TreeState {
|
||||||
if self.tree_state.borrow().is_none() {
|
self.tree_state.get_or_init(|| {
|
||||||
self.tree_state.replace(Some(TreeState::load(
|
TreeState::load(
|
||||||
self.store.clone(),
|
self.store.clone(),
|
||||||
self.working_copy_path.clone(),
|
self.working_copy_path.clone(),
|
||||||
self.state_path.clone(),
|
self.state_path.clone(),
|
||||||
)));
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_state(&self) -> Ref<TreeState> {
|
fn tree_state_mut(&mut self) -> &mut TreeState {
|
||||||
self.ensure_tree_state();
|
self.tree_state(); // ensure loaded
|
||||||
Ref::map(self.tree_state.borrow(), |o| o.as_ref().unwrap())
|
self.tree_state.get_mut().unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
fn tree_state_mut(&mut self) -> RefMut<TreeState> {
|
|
||||||
self.ensure_tree_state();
|
|
||||||
RefMut::map(self.tree_state.borrow_mut(), |o| o.as_mut().unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_tree_id(&self) -> TreeId {
|
pub fn current_tree_id(&self) -> TreeId {
|
||||||
|
@ -1102,7 +1098,7 @@ impl WorkingCopy {
|
||||||
self.load_proto();
|
self.load_proto();
|
||||||
// TODO: It's expensive to reload the whole tree. We should first check if it
|
// TODO: It's expensive to reload the whole tree. We should first check if it
|
||||||
// has changed.
|
// has changed.
|
||||||
self.tree_state.replace(None);
|
self.tree_state.take();
|
||||||
let old_operation_id = self.operation_id();
|
let old_operation_id = self.operation_id();
|
||||||
let old_tree_id = self.current_tree_id();
|
let old_tree_id = self.current_tree_id();
|
||||||
|
|
||||||
|
@ -1165,7 +1161,7 @@ impl LockedWorkingCopy<'_> {
|
||||||
// because the TreeState may be long-lived if the library is used in a
|
// because the TreeState may be long-lived if the library is used in a
|
||||||
// long-lived process.
|
// long-lived process.
|
||||||
pub fn snapshot(&mut self, base_ignores: Arc<GitIgnoreFile>) -> Result<TreeId, SnapshotError> {
|
pub fn snapshot(&mut self, base_ignores: Arc<GitIgnoreFile>) -> Result<TreeId, SnapshotError> {
|
||||||
let mut tree_state = self.wc.tree_state_mut();
|
let tree_state = self.wc.tree_state_mut();
|
||||||
self.tree_state_dirty |= tree_state.snapshot(base_ignores)?;
|
self.tree_state_dirty |= tree_state.snapshot(base_ignores)?;
|
||||||
Ok(tree_state.current_tree_id().clone())
|
Ok(tree_state.current_tree_id().clone())
|
||||||
}
|
}
|
||||||
|
@ -1219,7 +1215,7 @@ impl LockedWorkingCopy<'_> {
|
||||||
pub fn discard(mut self) {
|
pub fn discard(mut self) {
|
||||||
// Undo the changes in memory
|
// Undo the changes in memory
|
||||||
self.wc.load_proto();
|
self.wc.load_proto();
|
||||||
self.wc.tree_state.replace(None);
|
self.wc.tree_state.take();
|
||||||
self.tree_state_dirty = false;
|
self.tree_state_dirty = false;
|
||||||
self.closed = true;
|
self.closed = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue