rust/hg-cpython/src/revlog.rs
changeset 51233 9b06e7f32bc5
parent 51232 b8c89957a6b7
child 51234 62e39bef36ca
equal deleted inserted replaced
51232:b8c89957a6b7 51233:9b06e7f32bc5
    12 };
    12 };
    13 use cpython::{
    13 use cpython::{
    14     buffer::{Element, PyBuffer},
    14     buffer::{Element, PyBuffer},
    15     exc::{IndexError, ValueError},
    15     exc::{IndexError, ValueError},
    16     ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule,
    16     ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule,
    17     PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
    17     PyObject, PyResult, PySet, PyString, PyTuple, Python, PythonObject,
       
    18     ToPyObject,
    18 };
    19 };
    19 use hg::{
    20 use hg::{
    20     index::{IndexHeader, RevisionDataParams},
    21     errors::HgError,
       
    22     index::{IndexHeader, RevisionDataParams, SnapshotsCache},
    21     nodemap::{Block, NodeMapError, NodeTree},
    23     nodemap::{Block, NodeMapError, NodeTree},
    22     revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex},
    24     revlog::{nodemap::NodeMap, NodePrefix, RevlogError, RevlogIndex},
    23     BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
    25     BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
    24 };
    26 };
    25 use std::cell::RefCell;
    27 use std::cell::RefCell;
    26 
    28 
    27 /// Return a Struct implementing the Graph trait
    29 /// Return a Struct implementing the Graph trait
   269         Ok(result)
   271         Ok(result)
   270     }
   272     }
   271 
   273 
   272     /// Gather snapshot data in a cache dict
   274     /// Gather snapshot data in a cache dict
   273     def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> {
   275     def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> {
   274         self.call_cindex(py, "findsnapshots", args, kw)
   276         let index = self.index(py).borrow();
       
   277         let cache: PyDict = args.get_item(py, 0).extract(py)?;
       
   278         // this methods operates by setting new values in the cache,
       
   279         // hence we will compare results by letting the C implementation
       
   280         // operate over a deepcopy of the cache, and finally compare both
       
   281         // caches.
       
   282         let c_cache = PyDict::new(py);
       
   283         for (k, v) in cache.items(py) {
       
   284             c_cache.set_item(py, k, PySet::new(py, v)?)?;
       
   285         }
       
   286 
       
   287         let start_rev = UncheckedRevision(args.get_item(py, 1).extract(py)?);
       
   288         let end_rev = UncheckedRevision(args.get_item(py, 2).extract(py)?);
       
   289         let mut cache_wrapper = PySnapshotsCache{ py, dict: cache };
       
   290         index.find_snapshots(
       
   291             start_rev,
       
   292             end_rev,
       
   293             &mut cache_wrapper,
       
   294         ).map_err(|_| revlog_error(py))?;
       
   295 
       
   296         let c_args = PyTuple::new(
       
   297             py,
       
   298             &[
       
   299                 c_cache.clone_ref(py).into_object(),
       
   300                 args.get_item(py, 1),
       
   301                 args.get_item(py, 2)
       
   302             ]
       
   303         );
       
   304         self.call_cindex(py, "findsnapshots", &c_args, kw)?;
       
   305         assert_py_eq(py, "findsnapshots cache",
       
   306                      &cache_wrapper.into_object(),
       
   307                      &c_cache.into_object())?;
       
   308         Ok(py.None())
   275     }
   309     }
   276 
   310 
   277     /// determine revisions with deltas to reconstruct fulltext
   311     /// determine revisions with deltas to reconstruct fulltext
   278     def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
   312     def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
   279         self.call_cindex(py, "deltachain", args, kw)
   313         self.call_cindex(py, "deltachain", args, kw)
   485             params._rank.into_py_object(py).into_object(),
   519             params._rank.into_py_object(py).into_object(),
   486         ],
   520         ],
   487     )
   521     )
   488 }
   522 }
   489 
   523 
       
   524 struct PySnapshotsCache<'p> {
       
   525     py: Python<'p>,
       
   526     dict: PyDict,
       
   527 }
       
   528 
       
   529 impl<'p> PySnapshotsCache<'p> {
       
   530     fn into_object(self) -> PyObject {
       
   531         self.dict.into_object()
       
   532     }
       
   533 }
       
   534 
       
   535 impl<'p> SnapshotsCache for PySnapshotsCache<'p> {
       
   536     fn insert_for(
       
   537         &mut self,
       
   538         rev: BaseRevision,
       
   539         value: BaseRevision,
       
   540     ) -> Result<(), RevlogError> {
       
   541         let pyvalue = value.into_py_object(self.py).into_object();
       
   542         match self.dict.get_item(self.py, rev) {
       
   543             Some(obj) => obj
       
   544                 .extract::<PySet>(self.py)
       
   545                 .and_then(|set| set.add(self.py, pyvalue)),
       
   546             None => PySet::new(self.py, vec![pyvalue])
       
   547                 .and_then(|set| self.dict.set_item(self.py, rev, set)),
       
   548         }
       
   549         .map_err(|_| {
       
   550             RevlogError::Other(HgError::unsupported(
       
   551                 "Error in Python caches handling",
       
   552             ))
       
   553         })
       
   554     }
       
   555 }
       
   556 
   490 impl MixedIndex {
   557 impl MixedIndex {
   491     fn new(
   558     fn new(
   492         py: Python,
   559         py: Python,
   493         cindex: PyObject,
   560         cindex: PyObject,
   494         data: PyObject,
   561         data: PyObject,