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, |