566 and revlog.length(deltainfo.base) < deltainfo.deltalen): |
566 and revlog.length(deltainfo.base) < deltainfo.deltalen): |
567 return False |
567 return False |
568 |
568 |
569 return True |
569 return True |
570 |
570 |
|
571 def _candidategroups(revlog, p1, p2, cachedelta): |
|
572 """ |
|
573 Provides revisions that present an interest to be diffed against, |
|
574 grouped by level of easiness. |
|
575 """ |
|
576 gdelta = revlog._generaldelta |
|
577 curr = len(revlog) |
|
578 prev = curr - 1 |
|
579 p1r, p2r = revlog.rev(p1), revlog.rev(p2) |
|
580 |
|
581 # should we try to build a delta? |
|
582 if prev != nullrev and revlog._storedeltachains: |
|
583 tested = set() |
|
584 # This condition is true most of the time when processing |
|
585 # changegroup data into a generaldelta repo. The only time it |
|
586 # isn't true is if this is the first revision in a delta chain |
|
587 # or if ``format.generaldelta=true`` disabled ``lazydeltabase``. |
|
588 if cachedelta and gdelta and revlog._lazydeltabase: |
|
589 # Assume what we received from the server is a good choice |
|
590 # build delta will reuse the cache |
|
591 yield (cachedelta[0],) |
|
592 tested.add(cachedelta[0]) |
|
593 |
|
594 if gdelta: |
|
595 # exclude already lazy tested base if any |
|
596 parents = [p for p in (p1r, p2r) |
|
597 if p != nullrev and p not in tested] |
|
598 |
|
599 if not revlog._deltabothparents and len(parents) == 2: |
|
600 parents.sort() |
|
601 # To minimize the chance of having to build a fulltext, |
|
602 # pick first whichever parent is closest to us (max rev) |
|
603 yield (parents[1],) |
|
604 # then the other one (min rev) if the first did not fit |
|
605 yield (parents[0],) |
|
606 tested.update(parents) |
|
607 elif len(parents) > 0: |
|
608 # Test all parents (1 or 2), and keep the best candidate |
|
609 yield parents |
|
610 tested.update(parents) |
|
611 |
|
612 if prev not in tested: |
|
613 # other approach failed try against prev to hopefully save us a |
|
614 # fulltext. |
|
615 yield (prev,) |
|
616 tested.add(prev) |
|
617 |
571 class deltacomputer(object): |
618 class deltacomputer(object): |
572 def __init__(self, revlog): |
619 def __init__(self, revlog): |
573 self.revlog = revlog |
620 self.revlog = revlog |
574 |
|
575 def _getcandidaterevs(self, p1, p2, cachedelta): |
|
576 """ |
|
577 Provides revisions that present an interest to be diffed against, |
|
578 grouped by level of easiness. |
|
579 """ |
|
580 revlog = self.revlog |
|
581 gdelta = revlog._generaldelta |
|
582 curr = len(revlog) |
|
583 prev = curr - 1 |
|
584 p1r, p2r = revlog.rev(p1), revlog.rev(p2) |
|
585 |
|
586 # should we try to build a delta? |
|
587 if prev != nullrev and revlog._storedeltachains: |
|
588 tested = set() |
|
589 # This condition is true most of the time when processing |
|
590 # changegroup data into a generaldelta repo. The only time it |
|
591 # isn't true is if this is the first revision in a delta chain |
|
592 # or if ``format.generaldelta=true`` disabled ``lazydeltabase``. |
|
593 if cachedelta and gdelta and revlog._lazydeltabase: |
|
594 # Assume what we received from the server is a good choice |
|
595 # build delta will reuse the cache |
|
596 yield (cachedelta[0],) |
|
597 tested.add(cachedelta[0]) |
|
598 |
|
599 if gdelta: |
|
600 # exclude already lazy tested base if any |
|
601 parents = [p for p in (p1r, p2r) |
|
602 if p != nullrev and p not in tested] |
|
603 |
|
604 if not revlog._deltabothparents and len(parents) == 2: |
|
605 parents.sort() |
|
606 # To minimize the chance of having to build a fulltext, |
|
607 # pick first whichever parent is closest to us (max rev) |
|
608 yield (parents[1],) |
|
609 # then the other one (min rev) if the first did not fit |
|
610 yield (parents[0],) |
|
611 tested.update(parents) |
|
612 elif len(parents) > 0: |
|
613 # Test all parents (1 or 2), and keep the best candidate |
|
614 yield parents |
|
615 tested.update(parents) |
|
616 |
|
617 if prev not in tested: |
|
618 # other approach failed try against prev to hopefully save us a |
|
619 # fulltext. |
|
620 yield (prev,) |
|
621 tested.add(prev) |
|
622 |
621 |
623 def buildtext(self, revinfo, fh): |
622 def buildtext(self, revinfo, fh): |
624 """Builds a fulltext version of a revision |
623 """Builds a fulltext version of a revision |
625 |
624 |
626 revinfo: _revisioninfo instance that contains all needed info |
625 revinfo: _revisioninfo instance that contains all needed info |
733 deltalength = self.revlog.length |
732 deltalength = self.revlog.length |
734 deltaparent = self.revlog.deltaparent |
733 deltaparent = self.revlog.deltaparent |
735 |
734 |
736 deltainfo = None |
735 deltainfo = None |
737 deltas_limit = revinfo.textlen * LIMIT_DELTA2TEXT |
736 deltas_limit = revinfo.textlen * LIMIT_DELTA2TEXT |
738 for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta): |
737 groups = _candidategroups(self.revlog, p1, p2, cachedelta) |
|
738 for candidaterevs in groups: |
739 # filter out delta base that will never produce good delta |
739 # filter out delta base that will never produce good delta |
740 candidaterevs = [r for r in candidaterevs |
740 candidaterevs = [r for r in candidaterevs |
741 if self.revlog.length(r) <= deltas_limit] |
741 if self.revlog.length(r) <= deltas_limit] |
742 nominateddeltas = [] |
742 nominateddeltas = [] |
743 for candidaterev in candidaterevs: |
743 for candidaterev in candidaterevs: |