revisionstore: move DataStore::prefetch onto RemoteDataStore

Summary:
The RemoteDataStore is expected to be implemented into the higher level types,
while we don't want low level ones to pretend to have a prefetch method.

Reviewed By: quark-zju

Differential Revision: D17437893

fbshipit-source-id: 52ec90a6edf9aa5dac852fb827275be7fd361080
This commit is contained in:
Xavier Deguillard 2019-09-19 11:15:52 -07:00 committed by Facebook Github Bot
parent 5029409860
commit 77f25d449d
4 changed files with 26 additions and 7 deletions

View File

@ -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<T> {
@ -31,7 +31,7 @@ impl<T> ManifestStore<T> {
}
}
impl<T: DataStore> manifest::TreeStore for ManifestStore<T> {
impl<T: DataStore + RemoteDataStore> manifest::TreeStore for ManifestStore<T> {
fn get(&self, path: &RepoPath, node: Node) -> Fallible<Bytes> {
let key = Key::new(path.to_owned(), node);
self.underlying.get(&key).map(|data| Bytes::from(data))

View File

@ -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<Key>) -> Fallible<()> {
let gil = Python::acquire_gil();
let py = gil.python();

View File

@ -36,9 +36,18 @@ pub trait DataStore: LocalStore {
fn get_delta(&self, key: &Key) -> Fallible<Delta>;
fn get_delta_chain(&self, key: &Key) -> Fallible<Vec<Delta>>;
fn get_meta(&self, key: &Key) -> Fallible<Metadata>;
fn prefetch(&self, _keys: Vec<Key>) -> 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<Key>) -> Fallible<()>;
}
pub trait MutableDeltaStore: DataStore {
@ -63,6 +72,14 @@ impl<T: DataStore + ?Sized, U: Deref<Target = T>> 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<T: RemoteDataStore + ?Sized, U: Deref<Target = T>> RemoteDataStore for U {
fn prefetch(&self, keys: Vec<Key>) -> Fallible<()> {
T::prefetch(self, keys)
}
}
impl<T: MutableDeltaStore + ?Sized, U: Deref<Target = T>> MutableDeltaStore for U {
fn add(&self, delta: &Delta, metadata: &Metadata) -> Fallible<()> {
T::add(self, delta, metadata)

View File

@ -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;