65 } |
65 } |
66 } |
66 } |
67 |
67 |
68 /// `(full_path, entry, copy_source)` |
68 /// `(full_path, entry, copy_source)` |
69 type NodeDataMut<'a> = ( |
69 type NodeDataMut<'a> = ( |
70 &'a WithBasename<HgPathBuf>, |
70 &'a HgPath, |
71 &'a mut Option<DirstateEntry>, |
71 &'a mut Option<DirstateEntry>, |
72 &'a mut Option<HgPathBuf>, |
72 &'a mut Option<HgPathBuf>, |
73 ); |
73 ); |
74 |
74 |
75 impl<'on_disk> DirstateMap<'on_disk> { |
75 impl<'on_disk> DirstateMap<'on_disk> { |
246 node.entry = Some(new_entry) |
246 node.entry = Some(new_entry) |
247 } |
247 } |
248 |
248 |
249 fn iter_nodes<'a>( |
249 fn iter_nodes<'a>( |
250 &'a self, |
250 &'a self, |
251 ) -> impl Iterator<Item = (&'a WithBasename<HgPathBuf>, &'a Node)> + 'a |
251 ) -> impl Iterator<Item = (&'a HgPath, &'a Node)> + 'a { |
252 { |
|
253 // Depth first tree traversal. |
252 // Depth first tree traversal. |
254 // |
253 // |
255 // If we could afford internal iteration and recursion, |
254 // If we could afford internal iteration and recursion, |
256 // this would look like: |
255 // this would look like: |
257 // |
256 // |
274 std::iter::from_fn(move || { |
273 std::iter::from_fn(move || { |
275 while let Some((key, child_node)) = iter.next() { |
274 while let Some((key, child_node)) = iter.next() { |
276 // Pseudo-recursion |
275 // Pseudo-recursion |
277 let new_iter = child_node.children.iter(); |
276 let new_iter = child_node.children.iter(); |
278 let old_iter = std::mem::replace(&mut iter, new_iter); |
277 let old_iter = std::mem::replace(&mut iter, new_iter); |
|
278 let key = &**key.full_path(); |
279 stack.push((key, child_node, old_iter)); |
279 stack.push((key, child_node, old_iter)); |
280 } |
280 } |
281 // Found the end of a `children.iter()` iterator. |
281 // Found the end of a `children.iter()` iterator. |
282 if let Some((key, child_node, next_iter)) = stack.pop() { |
282 if let Some((key, child_node, next_iter)) = stack.pop() { |
283 // "Return" from pseudo-recursion by restoring state from the |
283 // "Return" from pseudo-recursion by restoring state from the |
305 let mut stack = Vec::new(); |
305 let mut stack = Vec::new(); |
306 let mut iter = self.root.iter_mut(); |
306 let mut iter = self.root.iter_mut(); |
307 std::iter::from_fn(move || { |
307 std::iter::from_fn(move || { |
308 while let Some((key, child_node)) = iter.next() { |
308 while let Some((key, child_node)) = iter.next() { |
309 // Pseudo-recursion |
309 // Pseudo-recursion |
310 let data = |
310 let data = ( |
311 (key, &mut child_node.entry, &mut child_node.copy_source); |
311 &**key.full_path(), |
|
312 &mut child_node.entry, |
|
313 &mut child_node.copy_source, |
|
314 ); |
312 let new_iter = child_node.children.iter_mut(); |
315 let new_iter = child_node.children.iter_mut(); |
313 let old_iter = std::mem::replace(&mut iter, new_iter); |
316 let old_iter = std::mem::replace(&mut iter, new_iter); |
314 stack.push((data, old_iter)); |
317 stack.push((data, old_iter)); |
315 } |
318 } |
316 // Found the end of a `children.values_mut()` iterator. |
319 // Found the end of a `children.values_mut()` iterator. |
419 // entries" set that need to be kept up to date |
422 // entries" set that need to be kept up to date |
420 } |
423 } |
421 |
424 |
422 fn non_normal_or_other_parent_paths( |
425 fn non_normal_or_other_parent_paths( |
423 &mut self, |
426 &mut self, |
424 ) -> Box<dyn Iterator<Item = &HgPathBuf> + '_> { |
427 ) -> Box<dyn Iterator<Item = &HgPath> + '_> { |
425 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
428 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
426 node.entry |
429 node.entry |
427 .as_ref() |
430 .as_ref() |
428 .filter(|entry| { |
431 .filter(|entry| { |
429 entry.is_non_normal() || entry.is_from_other_parent() |
432 entry.is_non_normal() || entry.is_from_other_parent() |
430 }) |
433 }) |
431 .map(|_| path.full_path()) |
434 .map(|_| path) |
432 })) |
435 })) |
433 } |
436 } |
434 |
437 |
435 fn set_non_normal_other_parent_entries(&mut self, _force: bool) { |
438 fn set_non_normal_other_parent_entries(&mut self, _force: bool) { |
436 // Do nothing, this `DirstateMap` does not have a separate "non normal |
439 // Do nothing, this `DirstateMap` does not have a separate "non normal |
437 // entries" and "from other parent" sets that need to be recomputed |
440 // entries" and "from other parent" sets that need to be recomputed |
438 } |
441 } |
439 |
442 |
440 fn iter_non_normal_paths( |
443 fn iter_non_normal_paths( |
441 &mut self, |
444 &mut self, |
442 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { |
445 ) -> Box<dyn Iterator<Item = &HgPath> + Send + '_> { |
443 self.iter_non_normal_paths_panic() |
446 self.iter_non_normal_paths_panic() |
444 } |
447 } |
445 |
448 |
446 fn iter_non_normal_paths_panic( |
449 fn iter_non_normal_paths_panic( |
447 &self, |
450 &self, |
448 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { |
451 ) -> Box<dyn Iterator<Item = &HgPath> + Send + '_> { |
449 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
452 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
450 node.entry |
453 node.entry |
451 .as_ref() |
454 .as_ref() |
452 .filter(|entry| entry.is_non_normal()) |
455 .filter(|entry| entry.is_non_normal()) |
453 .map(|_| path.full_path()) |
456 .map(|_| path) |
454 })) |
457 })) |
455 } |
458 } |
456 |
459 |
457 fn iter_other_parent_paths( |
460 fn iter_other_parent_paths( |
458 &mut self, |
461 &mut self, |
459 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { |
462 ) -> Box<dyn Iterator<Item = &HgPath> + Send + '_> { |
460 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
463 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
461 node.entry |
464 node.entry |
462 .as_ref() |
465 .as_ref() |
463 .filter(|entry| entry.is_from_other_parent()) |
466 .filter(|entry| entry.is_from_other_parent()) |
464 .map(|_| path.full_path()) |
467 .map(|_| path) |
465 })) |
468 })) |
466 } |
469 } |
467 |
470 |
468 fn has_tracked_dir( |
471 fn has_tracked_dir( |
469 &mut self, |
472 &mut self, |
500 // reallocations |
503 // reallocations |
501 let mut size = parents.as_bytes().len(); |
504 let mut size = parents.as_bytes().len(); |
502 for (path, node) in self.iter_nodes() { |
505 for (path, node) in self.iter_nodes() { |
503 if node.entry.is_some() { |
506 if node.entry.is_some() { |
504 size += packed_entry_size( |
507 size += packed_entry_size( |
505 path.full_path(), |
508 path, |
506 node.copy_source.as_ref(), |
509 node.copy_source.as_ref().map(|p| &**p), |
507 ) |
510 ) |
508 } |
511 } |
509 } |
512 } |
510 |
513 |
511 let mut packed = Vec::with_capacity(size); |
514 let mut packed = Vec::with_capacity(size); |
514 let now: i32 = now.0.try_into().expect("time overflow"); |
517 let now: i32 = now.0.try_into().expect("time overflow"); |
515 for (path, opt_entry, copy_source) in self.iter_node_data_mut() { |
518 for (path, opt_entry, copy_source) in self.iter_node_data_mut() { |
516 if let Some(entry) = opt_entry { |
519 if let Some(entry) = opt_entry { |
517 clear_ambiguous_mtime(entry, now); |
520 clear_ambiguous_mtime(entry, now); |
518 pack_entry( |
521 pack_entry( |
519 path.full_path(), |
522 path, |
520 entry, |
523 entry, |
521 copy_source.as_ref(), |
524 copy_source.as_ref().map(|p| &**p), |
522 &mut packed, |
525 &mut packed, |
523 ); |
526 ); |
524 } |
527 } |
525 } |
528 } |
526 Ok(packed) |
529 Ok(packed) |
555 |
558 |
556 fn copy_map_iter(&self) -> CopyMapIter<'_> { |
559 fn copy_map_iter(&self) -> CopyMapIter<'_> { |
557 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
560 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
558 node.copy_source |
561 node.copy_source |
559 .as_ref() |
562 .as_ref() |
560 .map(|copy_source| (path.full_path(), copy_source)) |
563 .map(|copy_source| (path, &**copy_source)) |
561 })) |
564 })) |
562 } |
565 } |
563 |
566 |
564 fn copy_map_contains_key(&self, key: &HgPath) -> bool { |
567 fn copy_map_contains_key(&self, key: &HgPath) -> bool { |
565 if let Some(node) = self.get_node(key) { |
568 if let Some(node) = self.get_node(key) { |
567 } else { |
570 } else { |
568 false |
571 false |
569 } |
572 } |
570 } |
573 } |
571 |
574 |
572 fn copy_map_get(&self, key: &HgPath) -> Option<&HgPathBuf> { |
575 fn copy_map_get(&self, key: &HgPath) -> Option<&HgPath> { |
573 self.get_node(key)?.copy_source.as_ref() |
576 self.get_node(key)?.copy_source.as_ref().map(|p| &**p) |
574 } |
577 } |
575 |
578 |
576 fn copy_map_remove(&mut self, key: &HgPath) -> Option<HgPathBuf> { |
579 fn copy_map_remove(&mut self, key: &HgPath) -> Option<HgPathBuf> { |
577 let count = &mut self.nodes_with_copy_source_count; |
580 let count = &mut self.nodes_with_copy_source_count; |
578 Self::get_node_mut(&mut self.root, key).and_then(|node| { |
581 Self::get_node_mut(&mut self.root, key).and_then(|node| { |
607 self.get_node(key)?.entry.as_ref() |
610 self.get_node(key)?.entry.as_ref() |
608 } |
611 } |
609 |
612 |
610 fn iter(&self) -> StateMapIter<'_> { |
613 fn iter(&self) -> StateMapIter<'_> { |
611 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
614 Box::new(self.iter_nodes().filter_map(|(path, node)| { |
612 node.entry.as_ref().map(|entry| (path.full_path(), entry)) |
615 node.entry.as_ref().map(|entry| (path, entry)) |
613 })) |
616 })) |
614 } |
617 } |
615 } |
618 } |