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