eager: share store between Rust and Python

Summary: This lets the Rust status operate with an up-to-date file/tree store when called from Python w/ pending changes.

Reviewed By: sggutier

Differential Revision: D47014121

fbshipit-source-id: cbef3d32fe85f7d3d0e086b6c723d6ce1ba3ee89
This commit is contained in:
Muir Manders 2023-06-27 00:01:50 -07:00 committed by Facebook GitHub Bot
parent ce3d776ca9
commit 26c8a319b6
6 changed files with 22 additions and 3 deletions

View File

@ -163,7 +163,7 @@ class fileslog(object):
self.contentstore = gitstore
self.filescmstore = gitstore
elif eagerepo.iseagerepo(repo):
store = eagerepo.openstore(repo)
store = repo._rsrepo.eagerstore()
self.contentstore = store
self.filescmstore = store
elif util.istest():

View File

@ -1861,7 +1861,8 @@ class localrepository(object):
# Rust may use it's own copies of stores, so we need to
# invalidate those when a transaction commits successfully.
repo._rsrepo.invalidatestores()
if not eagerepo.iseagerepo(self):
repo._rsrepo.invalidatestores()
# Don't invalidate Rust if Rust and Python are sharing the changelog object.
# Python's invalidation will cover it.

View File

@ -124,7 +124,7 @@ py_class!(class EagerRepo |py| {
}
});
py_class!(pub(crate) class EagerRepoStore |py| {
py_class!(pub class EagerRepoStore |py| {
data inner: RustEagerRepoStore;
/// Construct `EagerRepoStore` from a directory.

View File

@ -13,6 +13,7 @@ util = { path = "../../../../lib/util" }
parking_lot = "0.12.1"
pyconfigloader = { path = "../pyconfigloader" }
pydag = { path = "../pydag" }
pyeagerepo = { path = "../pyeagerepo" }
pyedenapi = { path = "../pyedenapi" }
pymetalog = { path = "../pymetalog" }
pyworkingcopy = { path = "../pyworkingcopy" }

View File

@ -22,6 +22,7 @@ use cpython_ext::PyPathBuf;
use parking_lot::RwLock;
use pyconfigloader::config;
use pydag::commits::commits as PyCommits;
use pyeagerepo::EagerRepoStore as PyEagerRepoStore;
use pyedenapi::PyClient as PyEdenApi;
use pymetalog::metalog as PyMetaLog;
use pyworkingcopy::workingcopy as PyWorkingCopy;
@ -148,6 +149,12 @@ py_class!(pub class repo |py| {
repolock::create_instance(py, Cell::new(Some(lock)))
}
}
def eagerstore(&self) -> PyResult<PyEagerRepoStore> {
let mut repo = self.inner(py).write();
let _ = repo.file_store().map_pyerr(py)?;
PyEagerRepoStore::create_instance(py, repo.eager_store().unwrap())
}
});
py_class!(pub class repolock |py| {

View File

@ -79,6 +79,7 @@ pub struct Repo {
file_scm_store: Option<Arc<scmstore::FileStore>>,
tree_store: Option<Arc<dyn RefreshableTreeStore + Send + Sync>>,
tree_scm_store: Option<Arc<scmstore::TreeStore>>,
eager_store: Option<EagerRepoStore>,
locker: Arc<RepoLocker>,
}
@ -197,6 +198,7 @@ impl Repo {
file_scm_store: None,
tree_store: None,
tree_scm_store: None,
eager_store: None,
locker,
})
}
@ -487,6 +489,7 @@ impl Repo {
Ok(fs)
}
// This should only be used to share stores with Python.
pub fn file_scm_store(&self) -> Option<Arc<scmstore::FileStore>> {
self.file_scm_store.clone()
}
@ -518,10 +521,16 @@ impl Repo {
Ok(ts)
}
// This should only be used to share stores with Python.
pub fn tree_scm_store(&self) -> Option<Arc<scmstore::TreeStore>> {
self.tree_scm_store.clone()
}
// This should only be used to share stores with Python.
pub fn eager_store(&self) -> Option<EagerRepoStore> {
self.eager_store.clone()
}
pub fn tree_resolver(&mut self) -> Result<TreeManifestResolver> {
Ok(TreeManifestResolver::new(
self.dag_commits()?,
@ -671,6 +680,7 @@ impl Repo {
}
if self.storage_format().is_eager() {
let store = EagerRepoStore::open(&self.store_path.join("hgcommits").join("v1"))?;
self.eager_store = Some(store.clone());
let store = Arc::new(store);
self.file_store = Some(store.clone());
self.tree_store = Some(store.clone());