Mercurial > public > mercurial-scm > hg
comparison rust/hg-cpython/src/revlog.rs @ 51209:9b06e7f32bc5
rust-index: add support for `find_snapshots`
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 03 Aug 2023 15:01:34 +0200 |
parents | b8c89957a6b7 |
children | 62e39bef36ca |
comparison
equal
deleted
inserted
replaced
51208:b8c89957a6b7 | 51209: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, |