Mercurial > hg
comparison rust/hg-cpython/src/revlog.rs @ 51219:8cb31833b486
rust-index: slicechunktodensity returns Rust result
Ready for removal of the scaffolding.
This time, we allow ourselves a minor optimization: we avoid
allocating for each chunk. Instead, we reuse the same vector,
and perform at most one allocation per chunk.
The `PyList` constructor will copy the buffer anyway.
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Sat, 30 Sep 2023 15:59:03 +0200 |
parents | 0112803e6c01 |
children | c817d9f626d3 |
comparison
equal
deleted
inserted
replaced
51218:0112803e6c01 | 51219:8cb31833b486 |
---|---|
363 args.get_item(py, 1).extract(py)?, | 363 args.get_item(py, 1).extract(py)?, |
364 args.get_item(py, 2).extract(py)? | 364 args.get_item(py, 2).extract(py)? |
365 )?; | 365 )?; |
366 | 366 |
367 let c_res = self.call_cindex(py, "slicechunktodensity", args, kw)?; | 367 let c_res = self.call_cindex(py, "slicechunktodensity", args, kw)?; |
368 assert_eq!( | 368 assert_py_eq(py, "slicechunktodensity", &rust_res, &c_res)?; |
369 rust_res.len(), | 369 Ok(rust_res) |
370 c_res.len(py)?, | |
371 "chunks differ {:?} {}", | |
372 rust_res, c_res | |
373 ); | |
374 for (i, chunk) in rust_res.iter().enumerate() { | |
375 let c_chunk = c_res.get_item(py, i)?; | |
376 assert_eq!( | |
377 chunk.len(), | |
378 c_chunk.len(py)?, | |
379 "chunk {} length differ {:?} {}", | |
380 i, | |
381 chunk, | |
382 c_res | |
383 ); | |
384 for (j, rev) in chunk.iter().enumerate() { | |
385 let c_chunk: BaseRevision | |
386 = c_chunk.get_item(py, j)?.extract(py)?; | |
387 assert_eq!(c_chunk, rev.0); | |
388 } | |
389 } | |
390 Ok(c_res) | |
391 } | 370 } |
392 | 371 |
393 /// stats for the index | 372 /// stats for the index |
394 def stats(&self, *args, **kw) -> PyResult<PyObject> { | 373 def stats(&self, *args, **kw) -> PyResult<PyObject> { |
395 self.call_cindex(py, "stats", args, kw) | 374 self.call_cindex(py, "stats", args, kw) |
854 &self, | 833 &self, |
855 py: Python, | 834 py: Python, |
856 revs: PyObject, | 835 revs: PyObject, |
857 target_density: f64, | 836 target_density: f64, |
858 min_gap_size: usize, | 837 min_gap_size: usize, |
859 ) -> PyResult<Vec<Vec<Revision>>> { | 838 ) -> PyResult<PyObject> { |
860 let index = &mut *self.index(py).borrow_mut(); | 839 let index = &mut *self.index(py).borrow_mut(); |
861 let revs: Vec<_> = rev_pyiter_collect(py, &revs, index)?; | 840 let revs: Vec<_> = rev_pyiter_collect(py, &revs, index)?; |
862 Ok(index.slice_chunk_to_density(&revs, target_density, min_gap_size)) | 841 let as_nested_vec = |
842 index.slice_chunk_to_density(&revs, target_density, min_gap_size); | |
843 let mut res = Vec::with_capacity(as_nested_vec.len()); | |
844 let mut py_chunk = Vec::new(); | |
845 for chunk in as_nested_vec { | |
846 py_chunk.clear(); | |
847 py_chunk.reserve_exact(chunk.len()); | |
848 for rev in chunk { | |
849 py_chunk.push( | |
850 PyRevision::from(rev).into_py_object(py).into_object(), | |
851 ); | |
852 } | |
853 res.push(PyList::new(py, &py_chunk).into_object()); | |
854 } | |
855 // This is just to do the same as C, not sure why it does this | |
856 if res.len() == 1 { | |
857 Ok(PyTuple::new(py, &res).into_object()) | |
858 } else { | |
859 Ok(PyList::new(py, &res).into_object()) | |
860 } | |
863 } | 861 } |
864 } | 862 } |
865 | 863 |
866 fn revlog_error(py: Python) -> PyErr { | 864 fn revlog_error(py: Python) -> PyErr { |
867 match py | 865 match py |