rust/hg-core/src/revlog/revlog.rs
changeset 48458 96ea4db4741b
parent 48457 1fb3615dfce2
child 48540 20d0d896183e
equal deleted inserted replaced
48457:1fb3615dfce2 48458:96ea4db4741b
   189             return Ok(vec![]);
   189             return Ok(vec![]);
   190         };
   190         };
   191         // Todo return -> Cow
   191         // Todo return -> Cow
   192         let mut entry = self.get_entry(rev)?;
   192         let mut entry = self.get_entry(rev)?;
   193         let mut delta_chain = vec![];
   193         let mut delta_chain = vec![];
   194         while let Some(base_rev) = entry.base_rev {
   194 
       
   195         // The meaning of `base_rev_or_base_of_delta_chain` depends on
       
   196         // generaldelta. See the doc on `ENTRY_DELTA_BASE` in
       
   197         // `mercurial/revlogutils/constants.py` and the code in
       
   198         // [_chaininfo] and in [index_deltachain].
       
   199         let uses_generaldelta = self.index.uses_generaldelta();
       
   200         while let Some(base_rev) = entry.base_rev_or_base_of_delta_chain {
       
   201             let base_rev = if uses_generaldelta {
       
   202                 base_rev
       
   203             } else {
       
   204                 entry.rev - 1
       
   205             };
   195             delta_chain.push(entry);
   206             delta_chain.push(entry);
   196             entry = self
   207             entry = self.get_entry_internal(base_rev)?;
   197                 .get_entry(base_rev)
       
   198                 .map_err(|_| RevlogError::corrupted())?;
       
   199         }
   208         }
   200 
   209 
   201         // TODO do not look twice in the index
   210         // TODO do not look twice in the index
   202         let index_entry = self
   211         let index_entry = self
   203             .index
   212             .index
   289         let entry = RevlogEntry {
   298         let entry = RevlogEntry {
   290             rev,
   299             rev,
   291             bytes: data,
   300             bytes: data,
   292             compressed_len: index_entry.compressed_len(),
   301             compressed_len: index_entry.compressed_len(),
   293             uncompressed_len: index_entry.uncompressed_len(),
   302             uncompressed_len: index_entry.uncompressed_len(),
   294             base_rev: if index_entry.base_revision() == rev {
   303             base_rev_or_base_of_delta_chain: if index_entry
       
   304                 .base_revision_or_base_of_delta_chain()
       
   305                 == rev
       
   306             {
   295                 None
   307                 None
   296             } else {
   308             } else {
   297                 Some(index_entry.base_revision())
   309                 Some(index_entry.base_revision_or_base_of_delta_chain())
   298             },
   310             },
   299         };
   311         };
   300         Ok(entry)
   312         Ok(entry)
       
   313     }
       
   314 
       
   315     /// when resolving internal references within revlog, any errors
       
   316     /// should be reported as corruption, instead of e.g. "invalid revision"
       
   317     fn get_entry_internal(
       
   318         &self,
       
   319         rev: Revision,
       
   320     ) -> Result<RevlogEntry, RevlogError> {
       
   321         return self.get_entry(rev).map_err(|_| RevlogError::corrupted());
   301     }
   322     }
   302 }
   323 }
   303 
   324 
   304 /// The revlog entry's bytes and the necessary informations to extract
   325 /// The revlog entry's bytes and the necessary informations to extract
   305 /// the entry's data.
   326 /// the entry's data.
   307 pub struct RevlogEntry<'a> {
   328 pub struct RevlogEntry<'a> {
   308     rev: Revision,
   329     rev: Revision,
   309     bytes: &'a [u8],
   330     bytes: &'a [u8],
   310     compressed_len: usize,
   331     compressed_len: usize,
   311     uncompressed_len: usize,
   332     uncompressed_len: usize,
   312     base_rev: Option<Revision>,
   333     base_rev_or_base_of_delta_chain: Option<Revision>,
   313 }
   334 }
   314 
   335 
   315 impl<'a> RevlogEntry<'a> {
   336 impl<'a> RevlogEntry<'a> {
   316     pub fn revision(&self) -> Revision {
   337     pub fn revision(&self) -> Revision {
   317         self.rev
   338         self.rev
   373     }
   394     }
   374 
   395 
   375     /// Tell if the entry is a snapshot or a delta
   396     /// Tell if the entry is a snapshot or a delta
   376     /// (influences on decompression).
   397     /// (influences on decompression).
   377     fn is_delta(&self) -> bool {
   398     fn is_delta(&self) -> bool {
   378         self.base_rev.is_some()
   399         self.base_rev_or_base_of_delta_chain.is_some()
   379     }
   400     }
   380 }
   401 }
   381 
   402 
   382 /// Calculate the hash of a revision given its data and its parents.
   403 /// Calculate the hash of a revision given its data and its parents.
   383 fn hash(
   404 fn hash(