Patchwork [2,of,2] unionrevlog: extract 'baserevision' and 'baserevdiff' methods

login
register
mail settings
Submitter Wojciech Lopata
Date Aug. 27, 2013, 12:47 a.m.
Message ID <ffbc95722db68cbef34d.1377564454@dev1179.prn1.facebook.com>
Download mbox | patch
Permalink /patch/2273/
State Accepted
Commit bb67f630b335270bcbd1f5a26c8d46b9edcd8775
Headers show

Comments

Wojciech Lopata - Aug. 27, 2013, 12:47 a.m.
# HG changeset patch
# User Wojciech Lopata <lopek@fb.com>
# Date 1377562261 25200
#      Mon Aug 26 17:11:01 2013 -0700
# Node ID ffbc95722db68cbef34d703645f569d83c3fb8a9
# Parent  05999156c4f06d3ec4da91303d5d6952523b038d
unionrevlog: extract 'baserevision' and 'baserevdiff' methods

This makes possible to use unionrevlog class with subclasses of revlog that
override revlog's 'revision' and 'revdiff' methods. In particular this change
is necessary to implement manifest compression, as it allows extension to
replace manifest class and override 'revision' amd 'revdiff' methods there.
Augie Fackler - Aug. 27, 2013, 3:19 p.m.
On Mon, Aug 26, 2013 at 05:47:34PM -0700, Wojciech Lopata wrote:
> # HG changeset patch
> # User Wojciech Lopata <lopek@fb.com>
> # Date 1377562261 25200
> #      Mon Aug 26 17:11:01 2013 -0700
> # Node ID ffbc95722db68cbef34d703645f569d83c3fb8a9
> # Parent  05999156c4f06d3ec4da91303d5d6952523b038d
> unionrevlog: extract 'baserevision' and 'baserevdiff' methods
>
> This makes possible to use unionrevlog class with subclasses of revlog that
> override revlog's 'revision' and 'revdiff' methods. In particular this change
> is necessary to implement manifest compression, as it allows extension to
> replace manifest class and override 'revision' amd 'revdiff' methods there.

Same question about inheriting default impls on this change.

>
> diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py
> --- a/mercurial/unionrepo.py
> +++ b/mercurial/unionrepo.py
> @@ -70,7 +70,7 @@
>                  self.revlog2.rev(self.node(rev1)),
>                  self.revlog2.rev(self.node(rev2)))
>          elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
> -            return revlog.revlog.revdiff(self, rev1, rev2)
> +            return self.baserevdiff(rev1, rev2)
>
>          return mdiff.textdiff(self.revision(self.node(rev1)),
>                                self.revision(self.node(rev2)))
> @@ -93,10 +93,20 @@
>              text = self.revlog2.revision(node)
>              self._cache = (node, rev, text)
>          else:
> -            text = revlog.revlog.revision(self, rev)
> +            text = self.baserevision(rev)
>              # already cached
>          return text
>
> +    def baserevision(self, nodeorrev):
> +        # Revlog subclasses may override 'revision' method to modify format of
> +        # content retrieved from revlog. To use unionrevlog with such class one
> +        # needs to override 'baserevision' and make more specific call here.
> +        return revlog.revlog.revision(self, nodeorrev)
> +
> +    def baserevdiff(self, rev1, rev2):
> +        # Exists for the same purpose as baserevision.
> +        return revlog.revlog.revdiff(self, rev1, rev2)
> +
>      def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
>          raise NotImplementedError
>      def addgroup(self, revs, linkmapper, transaction):
> @@ -114,6 +124,15 @@
>          unionrevlog.__init__(self, opener, self.indexfile, changelog2,
>                               linkmapper)
>
> +    def baserevision(self, nodeorrev):
> +        # Although changelog doesn't override 'revision' method, some extensions
> +        # may replace this class with another that does. Same story with
> +        # manifest and filelog classes.
> +        return changelog.changelog.revision(self, nodeorrev)
> +
> +    def baserevdiff(self, rev1, rev2):
> +        return changelog.changelog.revdiff(self, rev1, rev2)
> +
>  class unionmanifest(unionrevlog, manifest.manifest):
>      def __init__(self, opener, opener2, linkmapper):
>          manifest.manifest.__init__(self, opener)
> @@ -121,6 +140,12 @@
>          unionrevlog.__init__(self, opener, self.indexfile, manifest2,
>                               linkmapper)
>
> +    def baserevision(self, nodeorrev):
> +        return manifest.manifest.revision(self, nodeorrev)
> +
> +    def baserevdiff(self, rev1, rev2):
> +        return manifest.manifest.revdiff(self, rev1, rev2)
> +
>  class unionfilelog(unionrevlog, filelog.filelog):
>      def __init__(self, opener, path, opener2, linkmapper, repo):
>          filelog.filelog.__init__(self, opener, path)
> @@ -129,6 +154,12 @@
>                               linkmapper)
>          self._repo = repo
>
> +    def baserevision(self, nodeorrev):
> +        return filelog.filelog.revision(self, nodeorrev)
> +
> +    def baserevdiff(self, rev1, rev2):
> +        return filelog.filelog.revdiff(self, rev1, rev2)
> +
>      def _file(self, f):
>          self._repo.file(f)
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py
--- a/mercurial/unionrepo.py
+++ b/mercurial/unionrepo.py
@@ -70,7 +70,7 @@ 
                 self.revlog2.rev(self.node(rev1)),
                 self.revlog2.rev(self.node(rev2)))
         elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
-            return revlog.revlog.revdiff(self, rev1, rev2)
+            return self.baserevdiff(rev1, rev2)
 
         return mdiff.textdiff(self.revision(self.node(rev1)),
                               self.revision(self.node(rev2)))
@@ -93,10 +93,20 @@ 
             text = self.revlog2.revision(node)
             self._cache = (node, rev, text)
         else:
-            text = revlog.revlog.revision(self, rev)
+            text = self.baserevision(rev)
             # already cached
         return text
 
+    def baserevision(self, nodeorrev):
+        # Revlog subclasses may override 'revision' method to modify format of
+        # content retrieved from revlog. To use unionrevlog with such class one
+        # needs to override 'baserevision' and make more specific call here.
+        return revlog.revlog.revision(self, nodeorrev)
+
+    def baserevdiff(self, rev1, rev2):
+        # Exists for the same purpose as baserevision.
+        return revlog.revlog.revdiff(self, rev1, rev2)
+
     def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
         raise NotImplementedError
     def addgroup(self, revs, linkmapper, transaction):
@@ -114,6 +124,15 @@ 
         unionrevlog.__init__(self, opener, self.indexfile, changelog2,
                              linkmapper)
 
+    def baserevision(self, nodeorrev):
+        # Although changelog doesn't override 'revision' method, some extensions
+        # may replace this class with another that does. Same story with
+        # manifest and filelog classes.
+        return changelog.changelog.revision(self, nodeorrev)
+
+    def baserevdiff(self, rev1, rev2):
+        return changelog.changelog.revdiff(self, rev1, rev2)
+
 class unionmanifest(unionrevlog, manifest.manifest):
     def __init__(self, opener, opener2, linkmapper):
         manifest.manifest.__init__(self, opener)
@@ -121,6 +140,12 @@ 
         unionrevlog.__init__(self, opener, self.indexfile, manifest2,
                              linkmapper)
 
+    def baserevision(self, nodeorrev):
+        return manifest.manifest.revision(self, nodeorrev)
+
+    def baserevdiff(self, rev1, rev2):
+        return manifest.manifest.revdiff(self, rev1, rev2)
+
 class unionfilelog(unionrevlog, filelog.filelog):
     def __init__(self, opener, path, opener2, linkmapper, repo):
         filelog.filelog.__init__(self, opener, path)
@@ -129,6 +154,12 @@ 
                              linkmapper)
         self._repo = repo
 
+    def baserevision(self, nodeorrev):
+        return filelog.filelog.revision(self, nodeorrev)
+
+    def baserevdiff(self, rev1, rev2):
+        return filelog.filelog.revdiff(self, rev1, rev2)
+
     def _file(self, f):
         self._repo.file(f)