rust/hg-core/src/dirstate_tree/dirstate_map.rs
changeset 47192 1249eb9cc332
parent 47126 ecfe0819ada5
child 47193 47ccab19bf9f
equal deleted inserted replaced
47191:b338d831d18c 47192:1249eb9cc332
   151     /// other fields while the returned borrow is still valid
   151     /// other fields while the returned borrow is still valid
   152     fn get_node_mut<'tree>(
   152     fn get_node_mut<'tree>(
   153         root: &'tree mut ChildNodes<'on_disk>,
   153         root: &'tree mut ChildNodes<'on_disk>,
   154         path: &HgPath,
   154         path: &HgPath,
   155     ) -> Option<&'tree mut Node<'on_disk>> {
   155     ) -> Option<&'tree mut Node<'on_disk>> {
   156         Self::get_node_mut_tracing_ancestors(root, path, |_| {})
       
   157     }
       
   158 
       
   159     /// Same as `get_node_mut`, and calls `each_ancestor` for each ancestor of
       
   160     /// the node.
       
   161     ///
       
   162     /// Note that `each_ancestor` may be called (with what would be ancestors)
       
   163     /// even if it turns out there is no node at `path`.
       
   164     fn get_node_mut_tracing_ancestors<'tree>(
       
   165         root: &'tree mut ChildNodes<'on_disk>,
       
   166         path: &HgPath,
       
   167         mut each_ancestor: impl FnMut(&mut Node),
       
   168     ) -> Option<&'tree mut Node<'on_disk>> {
       
   169         let mut children = root;
   156         let mut children = root;
   170         let mut components = path.components();
   157         let mut components = path.components();
   171         let mut component =
   158         let mut component =
   172             components.next().expect("expected at least one components");
   159             components.next().expect("expected at least one components");
   173         loop {
   160         loop {
   174             let child = children.get_mut(component)?;
   161             let child = children.get_mut(component)?;
   175             if let Some(next_component) = components.next() {
   162             if let Some(next_component) = components.next() {
   176                 each_ancestor(child);
       
   177                 component = next_component;
   163                 component = next_component;
   178                 children = &mut child.children;
   164                 children = &mut child.children;
   179             } else {
   165             } else {
   180                 return Some(child);
   166                 return Some(child);
   181             }
   167             }
   367     fn drop_file(
   353     fn drop_file(
   368         &mut self,
   354         &mut self,
   369         filename: &HgPath,
   355         filename: &HgPath,
   370         old_state: EntryState,
   356         old_state: EntryState,
   371     ) -> Result<bool, DirstateMapError> {
   357     ) -> Result<bool, DirstateMapError> {
   372         let was_tracked = old_state.is_tracked();
   358         struct Dropped {
   373         if let Some(node) = Self::get_node_mut_tracing_ancestors(
   359             was_tracked: bool,
   374             &mut self.root,
   360             had_entry: bool,
   375             filename,
   361             had_copy_source: bool,
   376             |ancestor| {
   362         }
   377                 if was_tracked {
   363         fn recur(nodes: &mut ChildNodes, path: &HgPath) -> Option<Dropped> {
   378                     ancestor.tracked_descendants_count -= 1
   364             let (first_path_component, rest_of_path) =
       
   365                 path.split_first_component();
       
   366             let node = nodes.get_mut(first_path_component)?;
       
   367             let dropped;
       
   368             if let Some(rest) = rest_of_path {
       
   369                 dropped = recur(&mut node.children, rest)?;
       
   370                 if dropped.was_tracked {
       
   371                     node.tracked_descendants_count -= 1;
   379                 }
   372                 }
   380             },
   373             } else {
   381         ) {
   374                 dropped = Dropped {
   382             let had_entry = node.entry.is_some();
   375                     was_tracked: node
   383             let had_copy_source = node.copy_source.is_some();
   376                         .entry
   384 
   377                         .as_ref()
   385             // TODO: this leaves in the tree a "non-file" node. Should we
   378                         .map_or(false, |entry| entry.state.is_tracked()),
   386             // remove the node instead, together with ancestor nodes for
   379                     had_entry: node.entry.take().is_some(),
   387             // directories that become empty?
   380                     had_copy_source: node.copy_source.take().is_some(),
   388             node.entry = None;
   381                 };
   389             node.copy_source = None;
   382                 // TODO: this leaves in the tree a "non-file" node. Should we
   390 
   383                 // remove the node instead, together with ancestor nodes for
   391             if had_entry {
   384                 // directories that become empty?
       
   385             }
       
   386             Some(dropped)
       
   387         }
       
   388 
       
   389         if let Some(dropped) = recur(&mut self.root, filename) {
       
   390             if dropped.had_entry {
   392                 self.nodes_with_entry_count -= 1
   391                 self.nodes_with_entry_count -= 1
   393             }
   392             }
   394             if had_copy_source {
   393             if dropped.had_copy_source {
   395                 self.nodes_with_copy_source_count -= 1
   394                 self.nodes_with_copy_source_count -= 1
   396             }
   395             }
   397             Ok(had_entry)
   396             Ok(dropped.had_entry)
   398         } else {
   397         } else {
   399             assert!(!was_tracked);
   398             debug_assert!(!old_state.is_tracked());
   400             Ok(false)
   399             Ok(false)
   401         }
   400         }
   402     }
   401     }
   403 
   402 
   404     fn clear_ambiguous_times(&mut self, filenames: Vec<HgPathBuf>, now: i32) {
   403     fn clear_ambiguous_times(&mut self, filenames: Vec<HgPathBuf>, now: i32) {