mercurial/revlogutils/deltas.py
changeset 39361 507f5b1dd7c8
parent 39360 5d343a24bff5
child 39362 1441eb38849f
equal deleted inserted replaced
39360:5d343a24bff5 39361:507f5b1dd7c8
   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
   709         revinfo: information about the revision (instance of _revisioninfo)
   708         revinfo: information about the revision (instance of _revisioninfo)
   710         fh:      file handle to either the .i or the .d revlog file,
   709         fh:      file handle to either the .i or the .d revlog file,
   711                  depending on whether it is inlined or not
   710                  depending on whether it is inlined or not
   712 
   711 
   713         Returns the first acceptable candidate revision, as ordered by
   712         Returns the first acceptable candidate revision, as ordered by
   714         _getcandidaterevs
   713         _candidategroups
   715 
   714 
   716         If no suitable deltabase is found, we return delta info for a full
   715         If no suitable deltabase is found, we return delta info for a full
   717         snapshot.
   716         snapshot.
   718         """
   717         """
   719         if not revinfo.textlen:
   718         if not revinfo.textlen:
   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: