rust/hg-core/src/dirstate_tree/dirstate_map.rs
changeset 47347 73ddcedeaadf
parent 47337 0654b3b3d2b5
child 47348 a4de570e61fa
equal deleted inserted replaced
47346:5e12b6bfdd3e 47347:73ddcedeaadf
    44 /// path, so comparing full paths gives the same result as comparing base
    44 /// path, so comparing full paths gives the same result as comparing base
    45 /// names. However `HashMap` would waste time always re-hashing the same
    45 /// names. However `HashMap` would waste time always re-hashing the same
    46 /// string prefix.
    46 /// string prefix.
    47 pub(super) type NodeKey<'on_disk> = WithBasename<Cow<'on_disk, HgPath>>;
    47 pub(super) type NodeKey<'on_disk> = WithBasename<Cow<'on_disk, HgPath>>;
    48 
    48 
       
    49 /// Similar to `&'tree Cow<'on_disk, HgPath>`, but can also be returned
       
    50 /// for on-disk nodes that don’t actually have a `Cow` to borrow.
       
    51 pub(super) enum BorrowedPath<'tree, 'on_disk> {
       
    52     InMemory(&'tree HgPathBuf),
       
    53     OnDisk(&'on_disk HgPath),
       
    54 }
       
    55 
    49 pub(super) enum ChildNodes<'on_disk> {
    56 pub(super) enum ChildNodes<'on_disk> {
    50     InMemory(FastHashMap<NodeKey<'on_disk>, Node<'on_disk>>),
    57     InMemory(FastHashMap<NodeKey<'on_disk>, Node<'on_disk>>),
    51     OnDisk(&'on_disk [on_disk::Node]),
    58     OnDisk(&'on_disk [on_disk::Node]),
    52 }
    59 }
    53 
    60 
    57 }
    64 }
    58 
    65 
    59 pub(super) enum NodeRef<'tree, 'on_disk> {
    66 pub(super) enum NodeRef<'tree, 'on_disk> {
    60     InMemory(&'tree NodeKey<'on_disk>, &'tree Node<'on_disk>),
    67     InMemory(&'tree NodeKey<'on_disk>, &'tree Node<'on_disk>),
    61     OnDisk(&'on_disk on_disk::Node),
    68     OnDisk(&'on_disk on_disk::Node),
       
    69 }
       
    70 
       
    71 impl<'tree, 'on_disk> BorrowedPath<'tree, 'on_disk> {
       
    72     pub fn detach_from_tree(&self) -> Cow<'on_disk, HgPath> {
       
    73         match *self {
       
    74             BorrowedPath::InMemory(in_memory) => Cow::Owned(in_memory.clone()),
       
    75             BorrowedPath::OnDisk(on_disk) => Cow::Borrowed(on_disk),
       
    76         }
       
    77     }
       
    78 }
       
    79 
       
    80 impl<'tree, 'on_disk> std::ops::Deref for BorrowedPath<'tree, 'on_disk> {
       
    81     type Target = HgPath;
       
    82 
       
    83     fn deref(&self) -> &HgPath {
       
    84         match *self {
       
    85             BorrowedPath::InMemory(in_memory) => in_memory,
       
    86             BorrowedPath::OnDisk(on_disk) => on_disk,
       
    87         }
       
    88     }
    62 }
    89 }
    63 
    90 
    64 impl Default for ChildNodes<'_> {
    91 impl Default for ChildNodes<'_> {
    65     fn default() -> Self {
    92     fn default() -> Self {
    66         ChildNodes::InMemory(Default::default())
    93         ChildNodes::InMemory(Default::default())
   208             NodeRef::InMemory(path, _node) => Ok(path.full_path()),
   235             NodeRef::InMemory(path, _node) => Ok(path.full_path()),
   209             NodeRef::OnDisk(node) => node.full_path(on_disk),
   236             NodeRef::OnDisk(node) => node.full_path(on_disk),
   210         }
   237         }
   211     }
   238     }
   212 
   239 
   213     /// Returns a `Cow` that can borrow 'on_disk but is detached from 'tree
   240     /// Returns a `BorrowedPath`, which can be turned into a `Cow<'on_disk,
   214     pub(super) fn full_path_cow(
   241     /// HgPath>` detached from `'tree`
       
   242     pub(super) fn full_path_borrowed(
   215         &self,
   243         &self,
   216         on_disk: &'on_disk [u8],
   244         on_disk: &'on_disk [u8],
   217     ) -> Result<Cow<'on_disk, HgPath>, DirstateV2ParseError> {
   245     ) -> Result<BorrowedPath<'tree, 'on_disk>, DirstateV2ParseError> {
   218         match self {
   246         match self {
   219             NodeRef::InMemory(path, _node) => Ok(path.full_path().clone()),
   247             NodeRef::InMemory(path, _node) => match path.full_path() {
       
   248                 Cow::Borrowed(on_disk) => Ok(BorrowedPath::OnDisk(on_disk)),
       
   249                 Cow::Owned(in_memory) => Ok(BorrowedPath::InMemory(in_memory)),
       
   250             },
   220             NodeRef::OnDisk(node) => {
   251             NodeRef::OnDisk(node) => {
   221                 Ok(Cow::Borrowed(node.full_path(on_disk)?))
   252                 Ok(BorrowedPath::OnDisk(node.full_path(on_disk)?))
   222             }
   253             }
   223         }
   254         }
   224     }
   255     }
   225 
   256 
   226     pub(super) fn base_name(
   257     pub(super) fn base_name(
   817                 size += packed_entry_size(
   848                 size += packed_entry_size(
   818                     node.full_path(self.on_disk)?,
   849                     node.full_path(self.on_disk)?,
   819                     node.copy_source(self.on_disk)?,
   850                     node.copy_source(self.on_disk)?,
   820                 );
   851                 );
   821                 if entry.mtime_is_ambiguous(now) {
   852                 if entry.mtime_is_ambiguous(now) {
   822                     ambiguous_mtimes.push(node.full_path_cow(self.on_disk)?)
   853                     ambiguous_mtimes.push(
       
   854                         node.full_path_borrowed(self.on_disk)?
       
   855                             .detach_from_tree(),
       
   856                     )
   823                 }
   857                 }
   824             }
   858             }
   825         }
   859         }
   826         self.clear_known_ambiguous_mtimes(&ambiguous_mtimes)?;
   860         self.clear_known_ambiguous_mtimes(&ambiguous_mtimes)?;
   827 
   861 
   853         let mut paths = Vec::new();
   887         let mut paths = Vec::new();
   854         for node in self.iter_nodes() {
   888         for node in self.iter_nodes() {
   855             let node = node?;
   889             let node = node?;
   856             if let Some(entry) = node.entry()? {
   890             if let Some(entry) = node.entry()? {
   857                 if entry.mtime_is_ambiguous(now) {
   891                 if entry.mtime_is_ambiguous(now) {
   858                     paths.push(node.full_path_cow(self.on_disk)?)
   892                     paths.push(
       
   893                         node.full_path_borrowed(self.on_disk)?
       
   894                             .detach_from_tree(),
       
   895                     )
   859                 }
   896                 }
   860             }
   897             }
   861         }
   898         }
   862         // Borrow of `self` ends here since we collect cloned paths
   899         // Borrow of `self` ends here since we collect cloned paths
   863 
   900