rust/hg-core/src/dirstate_tree/dirstate_map.rs
changeset 47123 d8ac62374943
parent 47121 b6339a993b91
child 47124 cd8ca38fccff
equal deleted inserted replaced
47122:9aba0cde0ed9 47123:d8ac62374943
    22 use crate::PatternFileWarning;
    22 use crate::PatternFileWarning;
    23 use crate::StateMapIter;
    23 use crate::StateMapIter;
    24 use crate::StatusError;
    24 use crate::StatusError;
    25 use crate::StatusOptions;
    25 use crate::StatusOptions;
    26 
    26 
    27 pub struct DirstateMap {
    27 pub struct DirstateMap<'on_disk> {
       
    28     /// Contents of the `.hg/dirstate` file
       
    29     on_disk: &'on_disk [u8],
       
    30 
    28     pub(super) root: ChildNodes,
    31     pub(super) root: ChildNodes,
    29 
    32 
    30     /// Number of nodes anywhere in the tree that have `.entry.is_some()`.
    33     /// Number of nodes anywhere in the tree that have `.entry.is_some()`.
    31     nodes_with_entry_count: usize,
    34     nodes_with_entry_count: usize,
    32 
    35 
    67     &'a WithBasename<HgPathBuf>,
    70     &'a WithBasename<HgPathBuf>,
    68     &'a mut Option<DirstateEntry>,
    71     &'a mut Option<DirstateEntry>,
    69     &'a mut Option<HgPathBuf>,
    72     &'a mut Option<HgPathBuf>,
    70 );
    73 );
    71 
    74 
    72 impl DirstateMap {
    75 impl<'on_disk> DirstateMap<'on_disk> {
    73     pub fn new() -> Self {
    76     pub fn new(
    74         Self {
    77         on_disk: &'on_disk [u8],
       
    78     ) -> Result<(Self, Option<DirstateParents>), DirstateError> {
       
    79         let mut map = Self {
       
    80             on_disk,
    75             root: ChildNodes::default(),
    81             root: ChildNodes::default(),
    76             nodes_with_entry_count: 0,
    82             nodes_with_entry_count: 0,
    77             nodes_with_copy_source_count: 0,
    83             nodes_with_copy_source_count: 0,
    78         }
    84         };
       
    85         let parents = map.read()?;
       
    86         Ok((map, parents))
       
    87     }
       
    88 
       
    89     /// Should only be called in `new`
       
    90     #[timed]
       
    91     fn read(&mut self) -> Result<Option<DirstateParents>, DirstateError> {
       
    92         if self.on_disk.is_empty() {
       
    93             return Ok(None);
       
    94         }
       
    95 
       
    96         let parents = parse_dirstate_entries(
       
    97             self.on_disk,
       
    98             |path, entry, copy_source| {
       
    99                 let tracked = entry.state.is_tracked();
       
   100                 let node = Self::get_or_insert_node_tracing_ancestors(
       
   101                     &mut self.root,
       
   102                     path,
       
   103                     |ancestor| {
       
   104                         if tracked {
       
   105                             ancestor.tracked_descendants_count += 1
       
   106                         }
       
   107                     },
       
   108                 );
       
   109                 assert!(
       
   110                     node.entry.is_none(),
       
   111                     "duplicate dirstate entry in read"
       
   112                 );
       
   113                 assert!(
       
   114                     node.copy_source.is_none(),
       
   115                     "duplicate dirstate entry in read"
       
   116                 );
       
   117                 node.entry = Some(*entry);
       
   118                 node.copy_source = copy_source.map(HgPath::to_owned);
       
   119                 self.nodes_with_entry_count += 1;
       
   120                 if copy_source.is_some() {
       
   121                     self.nodes_with_copy_source_count += 1
       
   122                 }
       
   123             },
       
   124         )?;
       
   125 
       
   126         Ok(Some(parents.clone()))
    79     }
   127     }
    80 
   128 
    81     fn get_node(&self, path: &HgPath) -> Option<&Node> {
   129     fn get_node(&self, path: &HgPath) -> Option<&Node> {
    82         let mut children = &self.root;
   130         let mut children = &self.root;
    83         let mut components = path.components();
   131         let mut components = path.components();
   278             }
   326             }
   279         })
   327         })
   280     }
   328     }
   281 }
   329 }
   282 
   330 
   283 impl super::dispatch::DirstateMapMethods for DirstateMap {
   331 impl<'on_disk> super::dispatch::DirstateMapMethods for DirstateMap<'on_disk> {
   284     fn clear(&mut self) {
   332     fn clear(&mut self) {
   285         self.root.clear();
   333         self.root.clear();
   286         self.nodes_with_entry_count = 0;
   334         self.nodes_with_entry_count = 0;
   287         self.nodes_with_copy_source_count = 0;
   335         self.nodes_with_copy_source_count = 0;
   288     }
   336     }
   441         } else {
   489         } else {
   442             Ok(false)
   490             Ok(false)
   443         }
   491         }
   444     }
   492     }
   445 
   493 
   446     #[timed]
       
   447     fn read<'a>(
       
   448         &mut self,
       
   449         file_contents: &'a [u8],
       
   450     ) -> Result<Option<&'a DirstateParents>, DirstateError> {
       
   451         if file_contents.is_empty() {
       
   452             return Ok(None);
       
   453         }
       
   454 
       
   455         let parents = parse_dirstate_entries(
       
   456             file_contents,
       
   457             |path, entry, copy_source| {
       
   458                 let tracked = entry.state.is_tracked();
       
   459                 let node = Self::get_or_insert_node_tracing_ancestors(
       
   460                     &mut self.root,
       
   461                     path,
       
   462                     |ancestor| {
       
   463                         if tracked {
       
   464                             ancestor.tracked_descendants_count += 1
       
   465                         }
       
   466                     },
       
   467                 );
       
   468                 assert!(
       
   469                     node.entry.is_none(),
       
   470                     "duplicate dirstate entry in read"
       
   471                 );
       
   472                 assert!(
       
   473                     node.copy_source.is_none(),
       
   474                     "duplicate dirstate entry in read"
       
   475                 );
       
   476                 node.entry = Some(*entry);
       
   477                 node.copy_source = copy_source.map(HgPath::to_owned);
       
   478                 self.nodes_with_entry_count += 1;
       
   479                 if copy_source.is_some() {
       
   480                     self.nodes_with_copy_source_count += 1
       
   481                 }
       
   482             },
       
   483         )?;
       
   484 
       
   485         Ok(Some(parents))
       
   486     }
       
   487 
       
   488     fn pack(
   494     fn pack(
   489         &mut self,
   495         &mut self,
   490         parents: DirstateParents,
   496         parents: DirstateParents,
   491         now: Timestamp,
   497         now: Timestamp,
   492     ) -> Result<Vec<u8>, DirstateError> {
   498     ) -> Result<Vec<u8>, DirstateError> {