Patchwork [4,of,8,RFC] basectx: cache filectx generation for all contexts

login
register
mail settings
Submitter Sean Farley
Date Aug. 7, 2014, 7:52 p.m.
Message ID <6f2891408ace48a63386.1407441131@laptop.att.net>
Download mbox | patch
Permalink /patch/5320/
State Accepted
Headers show

Comments

Sean Farley - Aug. 7, 2014, 7:52 p.m.
# HG changeset patch
# User Sean Farley <sean.michael.farley@gmail.com>
# Date 1403899852 18000
#      Fri Jun 27 15:10:52 2014 -0500
# Node ID 6f2891408ace48a633862fd2b3dfb0ade1ab99db
# Parent  124225c16d40a0c2707e346c67e2a7a332ca0509
basectx: cache filectx generation for all contexts

Previously, filecontexts are generated on the fly but not cached. We need to
keep them around if we're going to allow the data inside to be changed.
Matt Mackall - Aug. 7, 2014, 9:47 p.m.
On Thu, 2014-08-07 at 14:52 -0500, Sean Farley wrote:
> # HG changeset patch
> # User Sean Farley <sean.michael.farley@gmail.com>
> # Date 1403899852 18000
> #      Fri Jun 27 15:10:52 2014 -0500
> # Node ID 6f2891408ace48a633862fd2b3dfb0ade1ab99db
> # Parent  124225c16d40a0c2707e346c67e2a7a332ca0509
> basectx: cache filectx generation for all contexts
> 
> Previously, filecontexts are generated on the fly but not cached. We need to
> keep them around if we're going to allow the data inside to be changed.

Seems problematic. In a case like convert, we'll potentially queue up
many megabytes in our cache (possibly larger than memory for initial
commits!), even though we have the ability to rebuild each file as
needed because we have a callable.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -31,10 +31,11 @@  class basectx(object):
         o = super(basectx, cls).__new__(cls)
 
         o._repo = repo
         o._rev = nullrev
         o._node = nullid
+        o._filectxs = {}
 
         return o
 
     def __str__(self):
         return short(self.node())
@@ -56,11 +57,17 @@  class basectx(object):
 
     def __contains__(self, key):
         return key in self._manifest
 
     def __getitem__(self, key):
-        return self.filectx(key)
+        try:
+            return self._filectxs[key]
+        except KeyError:
+            v = self.filectx(key)
+            self._filectxs[key] = v
+            return v
+
 
     def __iter__(self):
         for f in sorted(self._manifest):
             yield f