rust/hg-cpython/src/revlog.rs
changeset 51220 c817d9f626d3
parent 51219 8cb31833b486
child 51222 fc05dd74e907
equal deleted inserted replaced
51219:8cb31833b486 51220:c817d9f626d3
    18     PyModule, PyObject, PyResult, PySet, PyString, PyTuple, Python,
    18     PyModule, PyObject, PyResult, PySet, PyString, PyTuple, Python,
    19     PythonObject, ToPyObject,
    19     PythonObject, ToPyObject,
    20 };
    20 };
    21 use hg::{
    21 use hg::{
    22     errors::HgError,
    22     errors::HgError,
    23     index::{IndexHeader, RevisionDataParams, SnapshotsCache},
    23     index::{IndexHeader, Phase, RevisionDataParams, SnapshotsCache},
    24     nodemap::{Block, NodeMapError, NodeTree},
    24     nodemap::{Block, NodeMapError, NodeTree},
    25     revlog::{nodemap::NodeMap, NodePrefix, RevlogError, RevlogIndex},
    25     revlog::{nodemap::NodeMap, NodePrefix, RevlogError, RevlogIndex},
    26     BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
    26     BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
    27 };
    27 };
    28 use std::cell::RefCell;
    28 use std::{cell::RefCell, collections::HashMap};
    29 
    29 
    30 /// Return a Struct implementing the Graph trait
    30 /// Return a Struct implementing the Graph trait
    31 pub(crate) fn pyindex_to_graph(
    31 pub(crate) fn pyindex_to_graph(
    32     py: Python,
    32     py: Python,
    33     index: PyObject,
    33     index: PyObject,
   239         Ok(rust_res)
   239         Ok(rust_res)
   240     }
   240     }
   241 
   241 
   242     /// compute phases
   242     /// compute phases
   243     def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> {
   243     def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> {
   244         self.call_cindex(py, "computephasesmapsets", args, kw)
   244         let py_roots = args.get_item(py, 0).extract::<PyDict>(py)?;
       
   245         let rust_res = self.inner_computephasesmapsets(py, py_roots)?;
       
   246 
       
   247         let c_res = self.call_cindex(py, "computephasesmapsets", args, kw)?;
       
   248         assert_py_eq(py, "computephasesmapsets", &rust_res, &c_res)?;
       
   249         Ok(rust_res)
   245     }
   250     }
   246 
   251 
   247     /// reachableroots
   252     /// reachableroots
   248     def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> {
   253     def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> {
   249         self.call_cindex(py, "reachableroots2", args, kw)
   254         self.call_cindex(py, "reachableroots2", args, kw)
   827             .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
   832             .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
   828             .collect();
   833             .collect();
   829         Ok(PyList::new(py, &as_vec).into_object())
   834         Ok(PyList::new(py, &as_vec).into_object())
   830     }
   835     }
   831 
   836 
       
   837     fn inner_computephasesmapsets(
       
   838         &self,
       
   839         py: Python,
       
   840         py_roots: PyDict,
       
   841     ) -> PyResult<PyObject> {
       
   842         let index = &*self.index(py).borrow();
       
   843         let opt = self.get_nodetree(py)?.borrow();
       
   844         let nt = opt.as_ref().unwrap();
       
   845         let roots: Result<HashMap<Phase, Vec<Revision>>, PyErr> = py_roots
       
   846             .items_list(py)
       
   847             .iter(py)
       
   848             .map(|r| {
       
   849                 let phase = r.get_item(py, 0)?;
       
   850                 let nodes = r.get_item(py, 1)?;
       
   851                 // Transform the nodes from Python to revs here since we
       
   852                 // have access to the nodemap
       
   853                 let revs: Result<_, _> = nodes
       
   854                     .iter(py)?
       
   855                     .map(|node| match node?.extract::<PyBytes>(py) {
       
   856                         Ok(py_bytes) => {
       
   857                             let node = node_from_py_bytes(py, &py_bytes)?;
       
   858                             nt.find_bin(index, node.into())
       
   859                                 .map_err(|e| nodemap_error(py, e))?
       
   860                                 .ok_or_else(|| revlog_error(py))
       
   861                         }
       
   862                         Err(e) => Err(e),
       
   863                     })
       
   864                     .collect();
       
   865                 let phase = Phase::try_from(phase.extract::<usize>(py)?)
       
   866                     .map_err(|_| revlog_error(py));
       
   867                 Ok((phase?, revs?))
       
   868             })
       
   869             .collect();
       
   870         let (len, phase_maps) = index
       
   871             .compute_phases_map_sets(roots?)
       
   872             .map_err(|e| graph_error(py, e))?;
       
   873 
       
   874         // Ugly hack, but temporary
       
   875         const IDX_TO_PHASE_NUM: [usize; 4] = [1, 2, 32, 96];
       
   876         let py_phase_maps = PyDict::new(py);
       
   877         for (idx, roots) in phase_maps.iter().enumerate() {
       
   878             let phase_num = IDX_TO_PHASE_NUM[idx].into_py_object(py);
       
   879             // OPTIM too bad we have to collect here. At least, we could
       
   880             // reuse the same Vec and allocate it with capacity at
       
   881             // max(len(phase_maps)
       
   882             let roots_vec: Vec<PyInt> = roots
       
   883                 .iter()
       
   884                 .map(|r| PyRevision::from(*r).into_py_object(py))
       
   885                 .collect();
       
   886             py_phase_maps.set_item(
       
   887                 py,
       
   888                 phase_num,
       
   889                 PySet::new(py, roots_vec)?,
       
   890             )?;
       
   891         }
       
   892         Ok(PyTuple::new(
       
   893             py,
       
   894             &[
       
   895                 len.into_py_object(py).into_object(),
       
   896                 py_phase_maps.into_object(),
       
   897             ],
       
   898         )
       
   899         .into_object())
       
   900     }
       
   901 
   832     fn inner_slicechunktodensity(
   902     fn inner_slicechunktodensity(
   833         &self,
   903         &self,
   834         py: Python,
   904         py: Python,
   835         revs: PyObject,
   905         revs: PyObject,
   836         target_density: f64,
   906         target_density: f64,