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