Patchwork [3,of,6,RFC] repoview: establish an immutablerepoview class

login
register
mail settings
Submitter Gregory Szorc
Date June 9, 2017, 6:36 a.m.
Message ID <addfd306f838ccc177cc.1496990167@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/21275/
State Deferred
Headers show

Comments

Gregory Szorc - June 9, 2017, 6:36 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1496979889 25200
#      Thu Jun 08 20:44:49 2017 -0700
# Node ID addfd306f838ccc177cc68983bb6d41a585edd3e
# Parent  b101a96ea2cf32469c6e897d372c45608964613a
repoview: establish an immutablerepoview class

In pursuit of an immutable repo type, we establish a type to represent
an immutable repo view. The class definition is copied for performance
reasons. Proxying attribute lookups via proxies through an extra layer
of class hierarchy can add up. The implementation is simple enough,
so I don't think this is a big deal.

The only difference in implementation is the "changelog" attribute.
On the immutable type, it is a property cache. No cache validation
is involved. The benefits of this will become apparent in subsequent
commits.

Patch

diff --git a/mercurial/repoview.py b/mercurial/repoview.py
--- a/mercurial/repoview.py
+++ b/mercurial/repoview.py
@@ -15,6 +15,7 @@  from . import (
     obsolete,
     phases,
     tags as tagsmod,
+    util,
 )
 
 def hideablerevs(repo):
@@ -153,7 +154,7 @@  def filterrevs(repo, filtername):
         repo.filteredrevcache[filtername] = func(repo.unfiltered())
     return repo.filteredrevcache[filtername]
 
-class repoview(object):
+class immutablerepoview(object):
     """Provide a read/write view of a repo through a filtered changelog
 
     This object is used to access a filtered version of a repository without
@@ -191,6 +192,38 @@  class repoview(object):
     def __init__(self, repo, filtername):
         object.__setattr__(self, r'_unfilteredrepo', repo)
         object.__setattr__(self, r'filtername', filtername)
+
+    @util.propertycache
+    def changelog(self):
+        revs = filterrevs(self._unfilteredrepo, self.filtername)
+        cl = copy.copy(self._unfilteredrepo.changelog)
+        cl.filteredrevs = revs
+        return cl
+
+    def unfiltered(self):
+        """Return an unfiltered version of a repo"""
+        return self._unfilteredrepo
+
+    def filtered(self, name):
+        """Return a filtered version of a repository"""
+        if name == self.filtername:
+            return self
+        return self.unfiltered().filtered(name)
+
+    # Proxy to original repo.
+    def __getattr__(self, attr):
+        return getattr(self._unfilteredrepo, attr)
+
+    def __setattr__(self, attr, value):
+        return setattr(self._unfilteredrepo, attr, value)
+
+    def __delattr__(self, attr):
+        return delattr(self._unfilteredrepo, attr)
+
+class repoview(object):
+    def __init__(self, repo, filtername):
+        object.__setattr__(self, r'_unfilteredrepo', repo)
+        object.__setattr__(self, r'filtername', filtername)
         object.__setattr__(self, r'_clcachekey', None)
         object.__setattr__(self, r'_clcache', None)