changeset 49930 | e98fd81bb151 |
parent 49924 | 66ffe3749a48 |
child 49979 | f5b168979626 |
49929:5f1cd6839c69 | 49930:e98fd81bb151 |
---|---|
318 pub(super) fn copy_source( |
318 pub(super) fn copy_source( |
319 &self, |
319 &self, |
320 on_disk: &'on_disk [u8], |
320 on_disk: &'on_disk [u8], |
321 ) -> Result<Option<&'tree HgPath>, DirstateV2ParseError> { |
321 ) -> Result<Option<&'tree HgPath>, DirstateV2ParseError> { |
322 match self { |
322 match self { |
323 NodeRef::InMemory(_path, node) => { |
323 NodeRef::InMemory(_path, node) => Ok(node.copy_source.as_deref()), |
324 Ok(node.copy_source.as_ref().map(|s| &**s)) |
|
325 } |
|
326 NodeRef::OnDisk(node) => node.copy_source(on_disk), |
324 NodeRef::OnDisk(node) => node.copy_source(on_disk), |
327 } |
325 } |
328 } |
326 } |
329 /// Returns a `BorrowedPath`, which can be turned into a `Cow<'on_disk, |
327 /// Returns a `BorrowedPath`, which can be turned into a `Cow<'on_disk, |
330 /// HgPath>` detached from `'tree` |
328 /// HgPath>` detached from `'tree` |
338 node.copy_source.as_ref().map(|source| match source { |
336 node.copy_source.as_ref().map(|source| match source { |
339 Cow::Borrowed(on_disk) => BorrowedPath::OnDisk(on_disk), |
337 Cow::Borrowed(on_disk) => BorrowedPath::OnDisk(on_disk), |
340 Cow::Owned(in_memory) => BorrowedPath::InMemory(in_memory), |
338 Cow::Owned(in_memory) => BorrowedPath::InMemory(in_memory), |
341 }) |
339 }) |
342 } |
340 } |
343 NodeRef::OnDisk(node) => node |
341 NodeRef::OnDisk(node) => { |
344 .copy_source(on_disk)? |
342 node.copy_source(on_disk)?.map(BorrowedPath::OnDisk) |
345 .map(|source| BorrowedPath::OnDisk(source)), |
343 } |
346 }) |
344 }) |
347 } |
345 } |
348 |
346 |
349 pub(super) fn entry( |
347 pub(super) fn entry( |
350 &self, |
348 &self, |
416 } |
414 } |
417 } |
415 } |
418 |
416 |
419 impl NodeData { |
417 impl NodeData { |
420 fn has_entry(&self) -> bool { |
418 fn has_entry(&self) -> bool { |
421 match self { |
419 matches!(self, NodeData::Entry(_)) |
422 NodeData::Entry(_) => true, |
|
423 _ => false, |
|
424 } |
|
425 } |
420 } |
426 |
421 |
427 fn as_entry(&self) -> Option<&DirstateEntry> { |
422 fn as_entry(&self) -> Option<&DirstateEntry> { |
428 match self { |
423 match self { |
429 NodeData::Entry(entry) => Some(entry), |
424 NodeData::Entry(entry) => Some(entry), |
507 map.nodes_with_copy_source_count += 1 |
502 map.nodes_with_copy_source_count += 1 |
508 } |
503 } |
509 Ok(()) |
504 Ok(()) |
510 }, |
505 }, |
511 )?; |
506 )?; |
512 let parents = Some(parents.clone()); |
507 let parents = Some(*parents); |
513 |
508 |
514 Ok((map, parents)) |
509 Ok((map, parents)) |
515 } |
510 } |
516 |
511 |
517 /// Assuming dirstate-v2 format, returns whether the next write should |
512 /// Assuming dirstate-v2 format, returns whether the next write should |
679 ancestor.tracked_descendants_count = ancestor |
674 ancestor.tracked_descendants_count = ancestor |
680 .tracked_descendants_count |
675 .tracked_descendants_count |
681 .checked_sub(1) |
676 .checked_sub(1) |
682 .expect("tracked count to be >= 0"); |
677 .expect("tracked count to be >= 0"); |
683 } |
678 } |
684 } else { |
679 } else if wc_tracked { |
685 if wc_tracked { |
680 ancestor.tracked_descendants_count += 1; |
686 ancestor.tracked_descendants_count += 1; |
|
687 } |
|
688 } |
681 } |
689 })?; |
682 })?; |
690 |
683 |
691 let v2_data = if let Some(parent_file_data) = parent_file_data_opt { |
684 let v2_data = if let Some(parent_file_data) = parent_file_data_opt { |
692 DirstateV2Data { |
685 DirstateV2Data { |
732 } |
725 } |
733 |
726 |
734 ancestor.tracked_descendants_count += tracked_count_increment; |
727 ancestor.tracked_descendants_count += tracked_count_increment; |
735 })?; |
728 })?; |
736 if let Some(old_entry) = old_entry_opt { |
729 if let Some(old_entry) = old_entry_opt { |
737 let mut e = old_entry.clone(); |
730 let mut e = old_entry; |
738 if e.tracked() { |
731 if e.tracked() { |
739 // XXX |
732 // XXX |
740 // This is probably overkill for more case, but we need this to |
733 // This is probably overkill for more case, but we need this to |
741 // fully replace the `normallookup` call with `set_tracked` |
734 // fully replace the `normallookup` call with `set_tracked` |
742 // one. Consider smoothing this in the future. |
735 // one. Consider smoothing this in the future. |
773 .tracked_descendants_count |
766 .tracked_descendants_count |
774 .checked_sub(1) |
767 .checked_sub(1) |
775 .expect("tracked_descendants_count should be >= 0"); |
768 .expect("tracked_descendants_count should be >= 0"); |
776 })? |
769 })? |
777 .expect("node should exist"); |
770 .expect("node should exist"); |
778 let mut new_entry = old_entry.clone(); |
771 let mut new_entry = old_entry; |
779 new_entry.set_untracked(); |
772 new_entry.set_untracked(); |
780 node.data = NodeData::Entry(new_entry); |
773 node.data = NodeData::Entry(new_entry); |
781 Ok(()) |
774 Ok(()) |
782 } |
775 } |
783 |
776 |
801 if !old_entry.tracked() { |
794 if !old_entry.tracked() { |
802 ancestor.tracked_descendants_count += 1; |
795 ancestor.tracked_descendants_count += 1; |
803 } |
796 } |
804 })? |
797 })? |
805 .expect("node should exist"); |
798 .expect("node should exist"); |
806 let mut new_entry = old_entry.clone(); |
799 let mut new_entry = old_entry; |
807 new_entry.set_clean(mode, size, mtime); |
800 new_entry.set_clean(mode, size, mtime); |
808 node.data = NodeData::Entry(new_entry); |
801 node.data = NodeData::Entry(new_entry); |
809 Ok(()) |
802 Ok(()) |
810 } |
803 } |
811 |
804 |
1362 &mut self, |
1355 &mut self, |
1363 key: &HgPath, |
1356 key: &HgPath, |
1364 value: &HgPath, |
1357 value: &HgPath, |
1365 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> { |
1358 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> { |
1366 self.with_dmap_mut(|map| { |
1359 self.with_dmap_mut(|map| { |
1367 let node = map.get_or_insert_node(&key, |_ancestor| {})?; |
1360 let node = map.get_or_insert_node(key, |_ancestor| {})?; |
1368 let had_copy_source = node.copy_source.is_none(); |
1361 let had_copy_source = node.copy_source.is_none(); |
1369 let old = node |
1362 let old = node |
1370 .copy_source |
1363 .copy_source |
1371 .replace(value.to_owned().into()) |
1364 .replace(value.to_owned().into()) |
1372 .map(Cow::into_owned); |
1365 .map(Cow::into_owned); |
1862 |
1855 |
1863 // Shouldn't change anything since it's already not tracked |
1856 // Shouldn't change anything since it's already not tracked |
1864 map.set_untracked(p(b"some/nested/removed"))?; |
1857 map.set_untracked(p(b"some/nested/removed"))?; |
1865 assert_eq!(map.get_map().unreachable_bytes, 0); |
1858 assert_eq!(map.get_map().unreachable_bytes, 0); |
1866 |
1859 |
1867 match map.get_map().root { |
1860 if let ChildNodes::InMemory(_) = map.get_map().root { |
1868 ChildNodes::InMemory(_) => { |
1861 panic!("root should not have been mutated") |
1869 panic!("root should not have been mutated") |
|
1870 } |
|
1871 _ => (), |
|
1872 } |
1862 } |
1873 // We haven't mutated enough (nothing, actually), we should still be in |
1863 // We haven't mutated enough (nothing, actually), we should still be in |
1874 // the append strategy |
1864 // the append strategy |
1875 assert!(map.get_map().write_should_append()); |
1865 assert!(map.get_map().write_should_append()); |
1876 |
1866 |
1877 // But this mutates the structure, so there should be unreachable_bytes |
1867 // But this mutates the structure, so there should be unreachable_bytes |
1878 assert!(map.set_untracked(p(b"some/nested/added"))?); |
1868 assert!(map.set_untracked(p(b"some/nested/added"))?); |
1879 let unreachable_bytes = map.get_map().unreachable_bytes; |
1869 let unreachable_bytes = map.get_map().unreachable_bytes; |
1880 assert!(unreachable_bytes > 0); |
1870 assert!(unreachable_bytes > 0); |
1881 |
1871 |
1882 match map.get_map().root { |
1872 if let ChildNodes::OnDisk(_) = map.get_map().root { |
1883 ChildNodes::OnDisk(_) => panic!("root should have been mutated"), |
1873 panic!("root should have been mutated") |
1884 _ => (), |
|
1885 } |
1874 } |
1886 |
1875 |
1887 // This should not mutate the structure either, since `root` has |
1876 // This should not mutate the structure either, since `root` has |
1888 // already been mutated along with its direct children. |
1877 // already been mutated along with its direct children. |
1889 map.set_untracked(p(b"merged"))?; |
1878 map.set_untracked(p(b"merged"))?; |
1890 assert_eq!(map.get_map().unreachable_bytes, unreachable_bytes); |
1879 assert_eq!(map.get_map().unreachable_bytes, unreachable_bytes); |
1891 |
1880 |
1892 match map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap() { |
1881 if let NodeRef::InMemory(_, _) = |
1893 NodeRef::InMemory(_, _) => { |
1882 map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap() |
1894 panic!("'other/added_with_p2' should not have been mutated") |
1883 { |
1895 } |
1884 panic!("'other/added_with_p2' should not have been mutated") |
1896 _ => (), |
|
1897 } |
1885 } |
1898 // But this should, since it's in a different path |
1886 // But this should, since it's in a different path |
1899 // than `<root>some/nested/add` |
1887 // than `<root>some/nested/add` |
1900 map.set_untracked(p(b"other/added_with_p2"))?; |
1888 map.set_untracked(p(b"other/added_with_p2"))?; |
1901 assert!(map.get_map().unreachable_bytes > unreachable_bytes); |
1889 assert!(map.get_map().unreachable_bytes > unreachable_bytes); |
1902 |
1890 |
1903 match map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap() { |
1891 if let NodeRef::OnDisk(_) = |
1904 NodeRef::OnDisk(_) => { |
1892 map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap() |
1905 panic!("'other/added_with_p2' should have been mutated") |
1893 { |
1906 } |
1894 panic!("'other/added_with_p2' should have been mutated") |
1907 _ => (), |
|
1908 } |
1895 } |
1909 |
1896 |
1910 // We have rewritten most of the tree, we should create a new file |
1897 // We have rewritten most of the tree, we should create a new file |
1911 assert!(!map.get_map().write_should_append()); |
1898 assert!(!map.get_map().write_should_append()); |
1912 |
1899 |