##// END OF EJS Templates
rust-index: add support for delta-chain computation
Raphaël Gomès -
r52106:62e39bef default
parent child Browse files
Show More
@@ -512,6 +512,50 b' impl Index {'
512 }
512 }
513 }
513 }
514
514
515 /// Obtain the delta chain for a revision.
516 ///
517 /// `stop_rev` specifies a revision to stop at. If not specified, we
518 /// stop at the base of the chain.
519 ///
520 /// Returns a 2-tuple of (chain, stopped) where `chain` is a vec of
521 /// revs in ascending order and `stopped` is a bool indicating whether
522 /// `stoprev` was hit.
523 pub fn delta_chain(
524 &self,
525 rev: Revision,
526 stop_rev: Option<Revision>,
527 ) -> Result<(Vec<Revision>, bool), HgError> {
528 let mut current_rev = rev;
529 let mut entry = self.get_entry(rev).unwrap();
530 let mut chain = vec![];
531 while current_rev.0 != entry.base_revision_or_base_of_delta_chain().0
532 && stop_rev.map(|r| r != current_rev).unwrap_or(true)
533 {
534 chain.push(current_rev);
535 let new_rev = if self.uses_generaldelta() {
536 entry.base_revision_or_base_of_delta_chain()
537 } else {
538 UncheckedRevision(current_rev.0 - 1)
539 };
540 if new_rev.0 == NULL_REVISION.0 {
541 break;
542 }
543 current_rev = self.check_revision(new_rev).ok_or_else(|| {
544 HgError::corrupted(format!("Revision {new_rev} out of range"))
545 })?;
546 entry = self.get_entry(current_rev).unwrap()
547 }
548
549 let stopped = if stop_rev.map(|r| current_rev == r).unwrap_or(false) {
550 true
551 } else {
552 chain.push(current_rev);
553 false
554 };
555 chain.reverse();
556 Ok((chain, stopped))
557 }
558
515 pub fn find_snapshots(
559 pub fn find_snapshots(
516 &self,
560 &self,
517 start_rev: UncheckedRevision,
561 start_rev: UncheckedRevision,
@@ -310,7 +310,40 b' py_class!(pub class MixedIndex |py| {'
310
310
311 /// determine revisions with deltas to reconstruct fulltext
311 /// determine revisions with deltas to reconstruct fulltext
312 def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
312 def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
313 self.call_cindex(py, "deltachain", args, kw)
313 let index = self.index(py).borrow();
314 let rev = args.get_item(py, 0).extract::<BaseRevision>(py)?.into();
315 let stop_rev =
316 args.get_item(py, 1).extract::<Option<BaseRevision>>(py)?;
317 let rev = index.check_revision(rev).ok_or_else(|| {
318 nodemap_error(py, NodeMapError::RevisionNotInIndex(rev))
319 })?;
320 let stop_rev = if let Some(stop_rev) = stop_rev {
321 let stop_rev = UncheckedRevision(stop_rev);
322 Some(index.check_revision(stop_rev).ok_or_else(|| {
323 nodemap_error(py, NodeMapError::RevisionNotInIndex(stop_rev))
324 })?)
325 } else {None};
326 let (chain, stopped) = index.delta_chain(rev, stop_rev).map_err(|e| {
327 PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string())
328 })?;
329
330 let cresult = self.call_cindex(py, "deltachain", args, kw)?;
331 let cchain: Vec<BaseRevision> =
332 cresult.get_item(py, 0)?.extract::<Vec<BaseRevision>>(py)?;
333 let chain: Vec<_> = chain.into_iter().map(|r| r.0).collect();
334 assert_eq!(chain, cchain);
335 assert_eq!(stopped, cresult.get_item(py, 1)?.extract(py)?);
336
337 Ok(
338 PyTuple::new(
339 py,
340 &[
341 chain.into_py_object(py).into_object(),
342 stopped.into_py_object(py).into_object()
343 ]
344 ).into_object()
345 )
346
314 }
347 }
315
348
316 /// slice planned chunk read to reach a density threshold
349 /// slice planned chunk read to reach a density threshold
General Comments 0
You need to be logged in to leave comments. Login now