##// END OF EJS Templates
rust-dirstatemap: add simpler method `get_or_insert_node` for the common case...
Raphaël Gomès -
r50021:3926bfef default
parent child Browse files
Show More
@@ -478,7 +478,7 b" impl<'on_disk> DirstateMap<'on_disk> {"
478 map.on_disk,
478 map.on_disk,
479 |path, entry, copy_source| {
479 |path, entry, copy_source| {
480 let tracked = entry.state().is_tracked();
480 let tracked = entry.state().is_tracked();
481 let node = Self::get_or_insert_node(
481 let node = Self::get_or_insert_node_inner(
482 map.on_disk,
482 map.on_disk,
483 &mut map.unreachable_bytes,
483 &mut map.unreachable_bytes,
484 &mut map.root,
484 &mut map.root,
@@ -574,7 +574,30 b" impl<'on_disk> DirstateMap<'on_disk> {"
574 }
574 }
575 }
575 }
576
576
577 /// Get a mutable reference to the node at `path`, creating it if it does
578 /// not exist.
579 ///
580 /// `each_ancestor` is a callback that is called for each ancestor node
581 /// when descending the tree. It is used to keep the different counters
582 /// of the `DirstateMap` up-to-date.
577 fn get_or_insert_node<'tree, 'path>(
583 fn get_or_insert_node<'tree, 'path>(
584 &'tree mut self,
585 path: &'path HgPath,
586 each_ancestor: impl FnMut(&mut Node),
587 ) -> Result<&'tree mut Node<'on_disk>, DirstateV2ParseError> {
588 Self::get_or_insert_node_inner(
589 self.on_disk,
590 &mut self.unreachable_bytes,
591 &mut self.root,
592 path,
593 WithBasename::to_cow_owned,
594 each_ancestor,
595 )
596 }
597
598 /// Lower-level version of `get_or_insert_node_inner`, which is used when
599 /// parsing disk data to remove allocations for new nodes.
600 fn get_or_insert_node_inner<'tree, 'path>(
578 on_disk: &'on_disk [u8],
601 on_disk: &'on_disk [u8],
579 unreachable_bytes: &mut u32,
602 unreachable_bytes: &mut u32,
580 root: &'tree mut ChildNodes<'on_disk>,
603 root: &'tree mut ChildNodes<'on_disk>,
@@ -620,30 +643,23 b" impl<'on_disk> DirstateMap<'on_disk> {"
620 Some(old_entry) => (true, old_entry.tracked()),
643 Some(old_entry) => (true, old_entry.tracked()),
621 None => (false, false),
644 None => (false, false),
622 };
645 };
623 let node = Self::get_or_insert_node(
646 let node = self.get_or_insert_node(filename, |ancestor| {
624 self.on_disk,
647 if !had_entry {
625 &mut self.unreachable_bytes,
648 ancestor.descendants_with_entry_count += 1;
626 &mut self.root,
649 }
627 filename,
650 if was_tracked {
628 WithBasename::to_cow_owned,
651 if !wc_tracked {
629 |ancestor| {
652 ancestor.tracked_descendants_count = ancestor
630 if !had_entry {
653 .tracked_descendants_count
631 ancestor.descendants_with_entry_count += 1;
654 .checked_sub(1)
655 .expect("tracked count to be >= 0");
632 }
656 }
633 if was_tracked {
657 } else {
634 if !wc_tracked {
658 if wc_tracked {
635 ancestor.tracked_descendants_count = ancestor
659 ancestor.tracked_descendants_count += 1;
636 .tracked_descendants_count
637 .checked_sub(1)
638 .expect("tracked count to be >= 0");
639 }
640 } else {
641 if wc_tracked {
642 ancestor.tracked_descendants_count += 1;
643 }
644 }
660 }
645 },
661 }
646 )?;
662 })?;
647
663
648 let v2_data = if let Some(parent_file_data) = parent_file_data_opt {
664 let v2_data = if let Some(parent_file_data) = parent_file_data_opt {
649 DirstateV2Data {
665 DirstateV2Data {
@@ -666,10 +682,10 b" impl<'on_disk> DirstateMap<'on_disk> {"
666 ..Default::default()
682 ..Default::default()
667 }
683 }
668 };
684 };
685 node.data = NodeData::Entry(DirstateEntry::from_v2_data(v2_data));
669 if !had_entry {
686 if !had_entry {
670 self.nodes_with_entry_count += 1;
687 self.nodes_with_entry_count += 1;
671 }
688 }
672 node.data = NodeData::Entry(DirstateEntry::from_v2_data(v2_data));
673 Ok(())
689 Ok(())
674 }
690 }
675
691
@@ -683,21 +699,14 b" impl<'on_disk> DirstateMap<'on_disk> {"
683 let tracked_count_increment = if was_tracked { 0 } else { 1 };
699 let tracked_count_increment = if was_tracked { 0 } else { 1 };
684 let mut new = false;
700 let mut new = false;
685
701
686 let node = Self::get_or_insert_node(
702 let node = self.get_or_insert_node(filename, |ancestor| {
687 self.on_disk,
703 if !had_entry {
688 &mut self.unreachable_bytes,
704 ancestor.descendants_with_entry_count += 1;
689 &mut self.root,
705 }
690 filename,
691 WithBasename::to_cow_owned,
692 |ancestor| {
693 if !had_entry {
694 ancestor.descendants_with_entry_count += 1;
695 }
696
706
697 ancestor.tracked_descendants_count += tracked_count_increment;
707 ancestor.tracked_descendants_count += tracked_count_increment;
698 },
708 })?;
699 )?;
709 if let Some(old_entry) = old_entry_opt {
700 let new_entry = if let Some(old_entry) = old_entry_opt {
701 let mut e = old_entry.clone();
710 let mut e = old_entry.clone();
702 if e.tracked() {
711 if e.tracked() {
703 // XXX
712 // XXX
@@ -709,13 +718,12 b" impl<'on_disk> DirstateMap<'on_disk> {"
709 new = true;
718 new = true;
710 e.set_tracked();
719 e.set_tracked();
711 }
720 }
712 e
721 node.data = NodeData::Entry(e)
713 } else {
722 } else {
723 node.data = NodeData::Entry(DirstateEntry::new_tracked());
714 self.nodes_with_entry_count += 1;
724 self.nodes_with_entry_count += 1;
715 new = true;
725 new = true;
716 DirstateEntry::new_tracked()
717 };
726 };
718 node.data = NodeData::Entry(new_entry);
719 Ok(new)
727 Ok(new)
720 }
728 }
721
729
@@ -726,19 +734,12 b" impl<'on_disk> DirstateMap<'on_disk> {"
726 filename: &HgPath,
734 filename: &HgPath,
727 old_entry: DirstateEntry,
735 old_entry: DirstateEntry,
728 ) -> Result<(), DirstateV2ParseError> {
736 ) -> Result<(), DirstateV2ParseError> {
729 let node = Self::get_or_insert_node(
737 let node = self.get_or_insert_node(filename, |ancestor| {
730 self.on_disk,
738 ancestor.tracked_descendants_count = ancestor
731 &mut self.unreachable_bytes,
739 .tracked_descendants_count
732 &mut self.root,
740 .checked_sub(1)
733 filename,
741 .expect("tracked_descendants_count should be >= 0");
734 WithBasename::to_cow_owned,
742 })?;
735 |ancestor| {
736 ancestor.tracked_descendants_count = ancestor
737 .tracked_descendants_count
738 .checked_sub(1)
739 .expect("tracked_descendants_count should be >= 0");
740 },
741 )?;
742 let mut new_entry = old_entry.clone();
743 let mut new_entry = old_entry.clone();
743 new_entry.set_untracked();
744 new_entry.set_untracked();
744 node.data = NodeData::Entry(new_entry);
745 node.data = NodeData::Entry(new_entry);
@@ -753,18 +754,11 b" impl<'on_disk> DirstateMap<'on_disk> {"
753 size: u32,
754 size: u32,
754 mtime: TruncatedTimestamp,
755 mtime: TruncatedTimestamp,
755 ) -> Result<(), DirstateError> {
756 ) -> Result<(), DirstateError> {
756 let node = Self::get_or_insert_node(
757 let node = self.get_or_insert_node(filename, |ancestor| {
757 self.on_disk,
758 if !old_entry.tracked() {
758 &mut self.unreachable_bytes,
759 ancestor.tracked_descendants_count += 1;
759 &mut self.root,
760 }
760 filename,
761 })?;
761 WithBasename::to_cow_owned,
762 |ancestor| {
763 if !old_entry.tracked() {
764 ancestor.tracked_descendants_count += 1;
765 }
766 },
767 )?;
768 let mut new_entry = old_entry.clone();
762 let mut new_entry = old_entry.clone();
769 new_entry.set_clean(mode, size, mtime);
763 new_entry.set_clean(mode, size, mtime);
770 node.data = NodeData::Entry(new_entry);
764 node.data = NodeData::Entry(new_entry);
@@ -775,14 +769,7 b" impl<'on_disk> DirstateMap<'on_disk> {"
775 &mut self,
769 &mut self,
776 filename: &HgPath,
770 filename: &HgPath,
777 ) -> Result<(), DirstateError> {
771 ) -> Result<(), DirstateError> {
778 let node = Self::get_or_insert_node(
772 let node = self.get_or_insert_node(filename, |_ancestor| {})?;
779 self.on_disk,
780 &mut self.unreachable_bytes,
781 &mut self.root,
782 filename,
783 WithBasename::to_cow_owned,
784 |_ancestor| {},
785 )?;
786 let entry = node.data.as_entry_mut().expect("entry should exist");
773 let entry = node.data.as_entry_mut().expect("entry should exist");
787 entry.set_possibly_dirty();
774 entry.set_possibly_dirty();
788 node.data = NodeData::Entry(*entry);
775 node.data = NodeData::Entry(*entry);
@@ -1324,21 +1311,16 b' impl OwningDirstateMap {'
1324 value: &HgPath,
1311 value: &HgPath,
1325 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
1312 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
1326 self.with_dmap_mut(|map| {
1313 self.with_dmap_mut(|map| {
1327 let node = DirstateMap::get_or_insert_node(
1314 let node = map.get_or_insert_node(&key, |_ancestor| {})?;
1328 map.on_disk,
1315 let had_copy_source = node.copy_source.is_none();
1329 &mut map.unreachable_bytes,
1316 let old = node
1330 &mut map.root,
1317 .copy_source
1331 &key,
1318 .replace(value.to_owned().into())
1332 WithBasename::to_cow_owned,
1319 .map(Cow::into_owned);
1333 |_ancestor| {},
1320 if had_copy_source {
1334 )?;
1335 if node.copy_source.is_none() {
1336 map.nodes_with_copy_source_count += 1
1321 map.nodes_with_copy_source_count += 1
1337 }
1322 }
1338 Ok(node
1323 Ok(old)
1339 .copy_source
1340 .replace(value.to_owned().into())
1341 .map(Cow::into_owned))
1342 })
1324 })
1343 }
1325 }
1344
1326
@@ -1424,14 +1406,7 b' impl OwningDirstateMap {'
1424 }
1406 }
1425 self.with_dmap_mut(|map| {
1407 self.with_dmap_mut(|map| {
1426 for path in files_with_p2_info.iter() {
1408 for path in files_with_p2_info.iter() {
1427 let node = DirstateMap::get_or_insert_node(
1409 let node = map.get_or_insert_node(path, |_| {})?;
1428 map.on_disk,
1429 &mut map.unreachable_bytes,
1430 &mut map.root,
1431 path,
1432 WithBasename::to_cow_owned,
1433 |_| {},
1434 )?;
1435 let entry =
1410 let entry =
1436 node.data.as_entry_mut().expect("entry should exist");
1411 node.data.as_entry_mut().expect("entry should exist");
1437 entry.drop_merge_data();
1412 entry.drop_merge_data();
General Comments 0
You need to be logged in to leave comments. Login now