pydag: add a way to test commit existence without asking remote server

Summary: This will be used by upcoming changes.

Reviewed By: andll

Differential Revision: D29114048

fbshipit-source-id: ce963a42ebc5722ca9c61ab0a4e7a7377bbf7abb
This commit is contained in:
Jun Wu 2021-06-14 15:59:54 -07:00 committed by Facebook GitHub Bot
parent ac6c6cf3fa
commit f555f9c55d
2 changed files with 19 additions and 5 deletions

View File

@ -205,14 +205,15 @@ class changelog(object):
"""
return self.idmap.__contains__
def filternodes(self, nodes, inverse=False):
def filternodes(self, nodes, inverse=False, local=False):
"""Take a list of nodes, return a list of nodes present in the graph.
This will only send one remote request. Therefore more efficient than
"hasnode".
If inverse is True, return nodes not present in the graph instead.
If local is True, avoid asking remote servers (for a lazy changelog).
"""
return self.idmap.filternodes(nodes, inverse=inverse)
return self.idmap.filternodes(nodes, inverse=inverse, local=local)
@property
def torevs(self):

View File

@ -73,16 +73,29 @@ py_class!(pub class idmap |py| {
}
/// Filter out nodes not in the IdMap.
/// (nodes, inverse=False) -> nodes.
/// (nodes, inverse=False, local=False) -> nodes.
///
/// Use batching internally. Faster than checking `__contains__`
/// one by one.
///
/// If inverse is set to True, return missing nodes instead of
/// present nodes.
def filternodes(&self, nodes: Vec<PyBytes>, inverse: bool = false) -> PyResult<Vec<PyBytes>> {
///
/// If local is set to True, avoid contacting the remote server.
def filternodes(&self, nodes: Vec<PyBytes>, inverse: bool = false, local: bool = false) -> PyResult<Vec<PyBytes>> {
let map = self.map(py);
let vertexes: Vec<_> = nodes.iter().map(|n| Vertex::copy_from(n.data(py))).collect();
let mut vertexes: Vec<_> = nodes.iter().map(|n| Vertex::copy_from(n.data(py))).collect();
if local {
if inverse {
return Err(PyErr::new::<exc::ValueError, _>(py, "inverse and local cannot be both True"));
}
let contains = block_on(map.contains_vertex_name_locally(&vertexes)).map_pyerr(py)?;
vertexes = vertexes
.into_iter()
.zip(contains)
.filter_map(|(v, c)| if c { Some(v) } else { None }).collect();
};
let ids = block_on(map.vertex_id_batch(&vertexes)).map_pyerr(py)?;
let mut result = Vec::with_capacity(nodes.len());
for (node, id) in nodes.into_iter().zip(ids) {