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,