diff --git a/edenscmnative/bindings/modules/pymanifest/src/lib.rs b/edenscmnative/bindings/modules/pymanifest/src/lib.rs index 95a9d7d529..ede39c84a2 100644 --- a/edenscmnative/bindings/modules/pymanifest/src/lib.rs +++ b/edenscmnative/bindings/modules/pymanifest/src/lib.rs @@ -18,7 +18,7 @@ use manifest::{self, DiffType, FileMetadata, FileType, FsNode, Manifest}; use pathmatcher::{AlwaysMatcher, Matcher}; use pypathmatcher::PythonMatcher; use pyrevisionstore::PythonDataStore; -use revisionstore::DataStore; +use revisionstore::{DataStore, RemoteDataStore}; use types::{Key, Node, RepoPath, RepoPathBuf}; struct ManifestStore { @@ -31,7 +31,7 @@ impl ManifestStore { } } -impl manifest::TreeStore for ManifestStore { +impl manifest::TreeStore for ManifestStore { fn get(&self, path: &RepoPath, node: Node) -> Fallible { let key = Key::new(path.to_owned(), node); self.underlying.get(&key).map(|data| Bytes::from(data)) diff --git a/edenscmnative/bindings/modules/pyrevisionstore/src/pythondatastore.rs b/edenscmnative/bindings/modules/pyrevisionstore/src/pythondatastore.rs index d485116484..cc98d59b0b 100644 --- a/edenscmnative/bindings/modules/pyrevisionstore/src/pythondatastore.rs +++ b/edenscmnative/bindings/modules/pyrevisionstore/src/pythondatastore.rs @@ -8,7 +8,7 @@ use cpython::{ }; use failure::Fallible; -use revisionstore::{DataStore, Delta, LocalStore, Metadata}; +use revisionstore::{DataStore, Delta, LocalStore, Metadata, RemoteDataStore}; use types::Key; use crate::pyerror::pyerr_to_error; @@ -103,7 +103,9 @@ impl DataStore for PythonDataStore { let py_dict = PyDict::extract(py, &py_meta).map_err(|e| pyerr_to_error(py, e))?; to_metadata(py, &py_dict).map_err(|e| pyerr_to_error(py, e)) } +} +impl RemoteDataStore for PythonDataStore { fn prefetch(&self, keys: Vec) -> Fallible<()> { let gil = Python::acquire_gil(); let py = gil.python(); diff --git a/lib/revisionstore/src/datastore.rs b/lib/revisionstore/src/datastore.rs index 61dbc27b01..c5575a4f13 100644 --- a/lib/revisionstore/src/datastore.rs +++ b/lib/revisionstore/src/datastore.rs @@ -36,9 +36,18 @@ pub trait DataStore: LocalStore { fn get_delta(&self, key: &Key) -> Fallible; fn get_delta_chain(&self, key: &Key) -> Fallible>; fn get_meta(&self, key: &Key) -> Fallible; - fn prefetch(&self, _keys: Vec) -> Fallible<()> { - Ok(()) - } +} + +/// The `RemoteDataStore` trait indicates that data can fetched over the network. Care must be +/// taken to avoid serially fetching data and instead data should be fetched in bulk via the +/// `prefetch` API. +pub trait RemoteDataStore { + /// Attempt to bring the data corresponding to the passed in keys to a local store. + /// + /// When implemented on a pure remote store, like the `EdenApi`, the method will always fetch + /// everything that was asked. On a higher level store, such as the `ContentStore`, this will + /// avoid fetching data that is already present locally. + fn prefetch(&self, keys: Vec) -> Fallible<()>; } pub trait MutableDeltaStore: DataStore { @@ -63,6 +72,14 @@ impl> DataStore for U { } } +/// Implement `RemoteDataStore` for all types that can be `Deref` into a `RemoteDataStore`. This +/// includes all the smart pointers like `Box`, `Rc`, `Arc`. +impl> RemoteDataStore for U { + fn prefetch(&self, keys: Vec) -> Fallible<()> { + T::prefetch(self, keys) + } +} + impl> MutableDeltaStore for U { fn add(&self, delta: &Delta, metadata: &Metadata) -> Fallible<()> { T::add(self, delta, metadata) diff --git a/lib/revisionstore/src/lib.rs b/lib/revisionstore/src/lib.rs index 1df3ea987c..38c5d9fc84 100644 --- a/lib/revisionstore/src/lib.rs +++ b/lib/revisionstore/src/lib.rs @@ -31,7 +31,7 @@ pub mod unionhistorystore; pub use crate::contentstore::ContentStore; pub use crate::datapack::{DataEntry, DataPack, DataPackVersion}; -pub use crate::datastore::{DataStore, Delta, Metadata, MutableDeltaStore}; +pub use crate::datastore::{DataStore, Delta, Metadata, MutableDeltaStore, RemoteDataStore}; pub use crate::historypack::{HistoryEntry, HistoryPack, HistoryPackVersion}; pub use crate::historystore::{Ancestors, HistoryStore, MutableHistoryStore}; pub use crate::indexedlogdatastore::IndexedLogDataStore;