##// END OF EJS Templates
rust-dirstatemap: implement part of the `setparents` logic...
Raphaël Gomès -
r50011:3df46f3a default
parent child Browse files
Show More
@@ -593,22 +593,7 b' if rustmod is not None:'
593 self._dirtyparents = True
593 self._dirtyparents = True
594 copies = {}
594 copies = {}
595 if fold_p2:
595 if fold_p2:
596 # Collect into an intermediate list to avoid a `RuntimeError`
596 copies = self._map.setparents_fixup()
597 # exception due to mutation during iteration.
598 # TODO: move this the whole loop to Rust where `iter_mut`
599 # enables in-place mutation of elements of a collection while
600 # iterating it, without mutating the collection itself.
601 files_with_p2_info = [
602 f for f, s in self._map.items() if s.p2_info
603 ]
604 rust_map = self._map
605 for f in files_with_p2_info:
606 e = rust_map.get(f)
607 source = self.copymap.pop(f, None)
608 if source:
609 copies[f] = source
610 e.drop_merge_data()
611 rust_map.set_dirstate_item(f, e)
612 return copies
597 return copies
613
598
614 ### disk interaction
599 ### disk interaction
@@ -1375,6 +1375,41 b' impl OwningDirstateMap {'
1375 )))
1375 )))
1376 }
1376 }
1377
1377
1378 /// Only public because it needs to be exposed to the Python layer.
1379 /// It is not the full `setparents` logic, only the parts that mutate the
1380 /// entries.
1381 pub fn setparents_fixup(
1382 &mut self,
1383 ) -> Result<Vec<(HgPathBuf, HgPathBuf)>, DirstateV2ParseError> {
1384 // XXX
1385 // All the copying and re-querying is quite inefficient, but this is
1386 // still a lot better than doing it from Python.
1387 //
1388 // The better solution is to develop a mechanism for `iter_mut`,
1389 // which will be a lot more involved: we're dealing with a lazy,
1390 // append-mostly, tree-like data structure. This will do for now.
1391 let mut copies = vec![];
1392 let mut files_with_p2_info = vec![];
1393 for res in self.iter() {
1394 let (path, entry) = res?;
1395 if entry.p2_info() {
1396 files_with_p2_info.push(path.to_owned())
1397 }
1398 }
1399 self.with_dmap_mut(|map| {
1400 for path in files_with_p2_info.iter() {
1401 let node = map.get_or_insert(path)?;
1402 let entry =
1403 node.data.as_entry_mut().expect("entry should exist");
1404 entry.drop_merge_data();
1405 if let Some(source) = node.copy_source.take().as_deref() {
1406 copies.push((path.to_owned(), source.to_owned()));
1407 }
1408 }
1409 Ok(copies)
1410 })
1411 }
1412
1378 pub fn debug_iter(
1413 pub fn debug_iter(
1379 &self,
1414 &self,
1380 all: bool,
1415 all: bool,
@@ -489,6 +489,19 b' py_class!(pub class DirstateMap |py| {'
489 Ok(dirs)
489 Ok(dirs)
490 }
490 }
491
491
492 def setparents_fixup(&self) -> PyResult<PyDict> {
493 let dict = PyDict::new(py);
494 let copies = self.inner(py).borrow_mut().setparents_fixup();
495 for (key, value) in copies.map_err(|e| v2_error(py, e))? {
496 dict.set_item(
497 py,
498 PyBytes::new(py, key.as_bytes()),
499 PyBytes::new(py, value.as_bytes()),
500 )?;
501 }
502 Ok(dict)
503 }
504
492 def debug_iter(&self, all: bool) -> PyResult<PyList> {
505 def debug_iter(&self, all: bool) -> PyResult<PyList> {
493 let dirs = PyList::new(py, &[]);
506 let dirs = PyList::new(py, &[]);
494 for item in self.inner(py).borrow().debug_iter(all) {
507 for item in self.inner(py).borrow().debug_iter(all) {
General Comments 0
You need to be logged in to leave comments. Login now