rust/hg-core/src/dirstate_tree/dirstate_map.rs
changeset 49930 e98fd81bb151
parent 49924 66ffe3749a48
child 49979 f5b168979626
equal deleted inserted replaced
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