543 } |
543 } |
544 } |
544 } |
545 |
545 |
546 /// Returns a mutable reference to the node at `path` if it exists |
546 /// Returns a mutable reference to the node at `path` if it exists |
547 /// |
547 /// |
|
548 /// `each_ancestor` is a callback that is called for each ancestor node |
|
549 /// when descending the tree. It is used to keep the different counters |
|
550 /// of the `DirstateMap` up-to-date. |
|
551 fn get_node_mut<'tree>( |
|
552 &'tree mut self, |
|
553 path: &HgPath, |
|
554 each_ancestor: impl FnMut(&mut Node), |
|
555 ) -> Result<Option<&'tree mut Node<'on_disk>>, DirstateV2ParseError> { |
|
556 Self::get_node_mut_inner( |
|
557 self.on_disk, |
|
558 &mut self.unreachable_bytes, |
|
559 &mut self.root, |
|
560 path, |
|
561 each_ancestor, |
|
562 ) |
|
563 } |
|
564 |
|
565 /// Lower-level version of `get_node_mut`. |
|
566 /// |
548 /// This takes `root` instead of `&mut self` so that callers can mutate |
567 /// This takes `root` instead of `&mut self` so that callers can mutate |
549 /// other fields while the returned borrow is still valid. |
568 /// other fields while the returned borrow is still valid. |
550 /// |
569 /// |
551 /// `each_ancestor` is a callback that is called for each ancestor node |
570 /// `each_ancestor` is a callback that is called for each ancestor node |
552 /// when descending the tree. It is used to keep the different counters |
571 /// when descending the tree. It is used to keep the different counters |
553 /// of the `DirstateMap` up-to-date. |
572 /// of the `DirstateMap` up-to-date. |
554 fn get_node_mut<'tree>( |
573 fn get_node_mut_inner<'tree>( |
555 on_disk: &'on_disk [u8], |
574 on_disk: &'on_disk [u8], |
556 unreachable_bytes: &mut u32, |
575 unreachable_bytes: &mut u32, |
557 root: &'tree mut ChildNodes<'on_disk>, |
576 root: &'tree mut ChildNodes<'on_disk>, |
558 path: &HgPath, |
577 path: &HgPath, |
559 mut each_ancestor: impl FnMut(&mut Node), |
578 mut each_ancestor: impl FnMut(&mut Node), |
744 fn set_untracked( |
763 fn set_untracked( |
745 &mut self, |
764 &mut self, |
746 filename: &HgPath, |
765 filename: &HgPath, |
747 old_entry: DirstateEntry, |
766 old_entry: DirstateEntry, |
748 ) -> Result<(), DirstateV2ParseError> { |
767 ) -> Result<(), DirstateV2ParseError> { |
749 let node = DirstateMap::get_node_mut( |
768 let node = self |
750 self.on_disk, |
769 .get_node_mut(filename, |ancestor| { |
751 &mut self.unreachable_bytes, |
|
752 &mut self.root, |
|
753 filename, |
|
754 |ancestor| { |
|
755 ancestor.tracked_descendants_count = ancestor |
770 ancestor.tracked_descendants_count = ancestor |
756 .tracked_descendants_count |
771 .tracked_descendants_count |
757 .checked_sub(1) |
772 .checked_sub(1) |
758 .expect("tracked_descendants_count should be >= 0"); |
773 .expect("tracked_descendants_count should be >= 0"); |
759 }, |
774 })? |
760 )? |
775 .expect("node should exist"); |
761 .expect("node should exist"); |
|
762 let mut new_entry = old_entry.clone(); |
776 let mut new_entry = old_entry.clone(); |
763 new_entry.set_untracked(); |
777 new_entry.set_untracked(); |
764 node.data = NodeData::Entry(new_entry); |
778 node.data = NodeData::Entry(new_entry); |
765 Ok(()) |
779 Ok(()) |
766 } |
780 } |
778 old_entry: DirstateEntry, |
792 old_entry: DirstateEntry, |
779 mode: u32, |
793 mode: u32, |
780 size: u32, |
794 size: u32, |
781 mtime: TruncatedTimestamp, |
795 mtime: TruncatedTimestamp, |
782 ) -> Result<(), DirstateError> { |
796 ) -> Result<(), DirstateError> { |
783 let node = DirstateMap::get_node_mut( |
797 let node = self |
784 self.on_disk, |
798 .get_node_mut(filename, |ancestor| { |
785 &mut self.unreachable_bytes, |
|
786 &mut self.root, |
|
787 filename, |
|
788 |ancestor| { |
|
789 if !old_entry.tracked() { |
799 if !old_entry.tracked() { |
790 ancestor.tracked_descendants_count += 1; |
800 ancestor.tracked_descendants_count += 1; |
791 } |
801 } |
792 }, |
802 })? |
793 )? |
803 .expect("node should exist"); |
794 .expect("node should exist"); |
|
795 let mut new_entry = old_entry.clone(); |
804 let mut new_entry = old_entry.clone(); |
796 new_entry.set_clean(mode, size, mtime); |
805 new_entry.set_clean(mode, size, mtime); |
797 node.data = NodeData::Entry(new_entry); |
806 node.data = NodeData::Entry(new_entry); |
798 Ok(()) |
807 Ok(()) |
799 } |
808 } |
805 /// Panics if the node does not exist. |
814 /// Panics if the node does not exist. |
806 fn set_possibly_dirty( |
815 fn set_possibly_dirty( |
807 &mut self, |
816 &mut self, |
808 filename: &HgPath, |
817 filename: &HgPath, |
809 ) -> Result<(), DirstateError> { |
818 ) -> Result<(), DirstateError> { |
810 let node = DirstateMap::get_node_mut( |
819 let node = self |
811 self.on_disk, |
820 .get_node_mut(filename, |_ancestor| {})? |
812 &mut self.unreachable_bytes, |
821 .expect("node should exist"); |
813 &mut self.root, |
|
814 filename, |
|
815 |_ancestor| {}, |
|
816 )? |
|
817 .expect("node should exist"); |
|
818 let entry = node.data.as_entry_mut().expect("entry should exist"); |
822 let entry = node.data.as_entry_mut().expect("entry should exist"); |
819 entry.set_possibly_dirty(); |
823 entry.set_possibly_dirty(); |
820 node.data = NodeData::Entry(*entry); |
824 node.data = NodeData::Entry(*entry); |
821 Ok(()) |
825 Ok(()) |
822 } |
826 } |
824 /// Clears the cached mtime for the (potential) folder at `path`. |
828 /// Clears the cached mtime for the (potential) folder at `path`. |
825 pub(super) fn clear_cached_mtime( |
829 pub(super) fn clear_cached_mtime( |
826 &mut self, |
830 &mut self, |
827 path: &HgPath, |
831 path: &HgPath, |
828 ) -> Result<(), DirstateV2ParseError> { |
832 ) -> Result<(), DirstateV2ParseError> { |
829 let node = match DirstateMap::get_node_mut( |
833 let node = match self.get_node_mut(path, |_ancestor| {})? { |
830 self.on_disk, |
|
831 &mut self.unreachable_bytes, |
|
832 &mut self.root, |
|
833 path, |
|
834 |_ancestor| {}, |
|
835 )? { |
|
836 Some(node) => node, |
834 Some(node) => node, |
837 None => return Ok(()), |
835 None => return Ok(()), |
838 }; |
836 }; |
839 if let NodeData::CachedDirectory { .. } = &node.data { |
837 if let NodeData::CachedDirectory { .. } = &node.data { |
840 node.data = NodeData::None |
838 node.data = NodeData::None |
846 pub(super) fn set_cached_mtime( |
844 pub(super) fn set_cached_mtime( |
847 &mut self, |
845 &mut self, |
848 path: &HgPath, |
846 path: &HgPath, |
849 mtime: TruncatedTimestamp, |
847 mtime: TruncatedTimestamp, |
850 ) -> Result<(), DirstateV2ParseError> { |
848 ) -> Result<(), DirstateV2ParseError> { |
851 let node = match DirstateMap::get_node_mut( |
849 let node = match self.get_node_mut(path, |_ancestor| {})? { |
852 self.on_disk, |
|
853 &mut self.unreachable_bytes, |
|
854 &mut self.root, |
|
855 path, |
|
856 |_ancestor| {}, |
|
857 )? { |
|
858 Some(node) => node, |
850 Some(node) => node, |
859 None => return Ok(()), |
851 None => return Ok(()), |
860 }; |
852 }; |
861 match &node.data { |
853 match &node.data { |
862 NodeData::Entry(_) => {} // Don’t overwrite an entry |
854 NodeData::Entry(_) => {} // Don’t overwrite an entry |
1334 key: &HgPath, |
1326 key: &HgPath, |
1335 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> { |
1327 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> { |
1336 self.with_dmap_mut(|map| { |
1328 self.with_dmap_mut(|map| { |
1337 let count = &mut map.nodes_with_copy_source_count; |
1329 let count = &mut map.nodes_with_copy_source_count; |
1338 let unreachable_bytes = &mut map.unreachable_bytes; |
1330 let unreachable_bytes = &mut map.unreachable_bytes; |
1339 Ok(DirstateMap::get_node_mut( |
1331 Ok(DirstateMap::get_node_mut_inner( |
1340 map.on_disk, |
1332 map.on_disk, |
1341 unreachable_bytes, |
1333 unreachable_bytes, |
1342 &mut map.root, |
1334 &mut map.root, |
1343 key, |
1335 key, |
1344 |_ancestor| {}, |
1336 |_ancestor| {}, |