Mercurial > hg
changeset 46095:93e09d370003
treemanifest: stop storing full path for each item in manifest._lazydirs
This information is obtainable, if needed, based on the lazydirs key (which is
the entry name) and the manifest's `dir()` method.
### Performance
This is actually both a memory and a performance improvement, but it's likely to
be a very small one in most situations. In the pathological repo I've been using
for testing other performance work I've done recently, this reduced the time for
a rebase operation (rebasing two commits across a public-phase change that
touches a sibling of one of my tracked directories where the common parent is
massive (>>10k entries)):
#### Before
```
Time (mean ± σ): 4.059 s ± 0.121 s [User: 0.9 ms, System: 0.6 ms]
Range (min … max): 3.941 s … 4.352 s 10 runs
```
#### After
```
Time (mean ± σ): 3.707 s ± 0.060 s [User: 0.8 ms, System: 0.8 ms]
Range (min … max): 3.648 s … 3.818 s 10 runs
```
Differential Revision: https://phab.mercurial-scm.org/D9553
author | Kyle Lippincott <spectral@google.com> |
---|---|
date | Thu, 03 Dec 2020 14:39:39 -0800 |
parents | 1ced08423d59 |
children | 4d5e2fd53707 |
files | mercurial/manifest.py |
diffstat | 1 files changed, 13 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/manifest.py Tue Dec 08 10:51:05 2020 -0500 +++ b/mercurial/manifest.py Thu Dec 03 14:39:39 2020 -0800 @@ -818,23 +818,24 @@ def _loadalllazy(self): selfdirs = self._dirs - for d, (path, node, readsubtree, docopy) in pycompat.iteritems( + subpath = self._subpath + for d, (node, readsubtree, docopy) in pycompat.iteritems( self._lazydirs ): if docopy: - selfdirs[d] = readsubtree(path, node).copy() + selfdirs[d] = readsubtree(subpath(d), node).copy() else: - selfdirs[d] = readsubtree(path, node) + selfdirs[d] = readsubtree(subpath(d), node) self._lazydirs = {} def _loadlazy(self, d): v = self._lazydirs.get(d) if v: - path, node, readsubtree, docopy = v + node, readsubtree, docopy = v if docopy: - self._dirs[d] = readsubtree(path, node).copy() + self._dirs[d] = readsubtree(self._subpath(d), node).copy() else: - self._dirs[d] = readsubtree(path, node) + self._dirs[d] = readsubtree(self._subpath(d), node) del self._lazydirs[d] def _loadchildrensetlazy(self, visit): @@ -861,7 +862,7 @@ toloadlazy = [] for d, v1 in pycompat.iteritems(t1._lazydirs): v2 = t2._lazydirs.get(d) - if not v2 or v2[1] != v1[1]: + if not v2 or v2[0] != v1[0]: toloadlazy.append(d) for d, v1 in pycompat.iteritems(t2._lazydirs): if d not in t1._lazydirs: @@ -1092,8 +1093,8 @@ def _copyfunc(s): self._load() s._lazydirs = { - d: (p, n, r, True) - for d, (p, n, r, c) in pycompat.iteritems(self._lazydirs) + d: (n, r, True) + for d, (n, r, c) in pycompat.iteritems(self._lazydirs) } sdirs = s._dirs for d, v in pycompat.iteritems(self._dirs): @@ -1317,13 +1318,12 @@ def parse(self, text, readsubtree): selflazy = self._lazydirs - subpath = self._subpath for f, n, fl in _parse(text): if fl == b't': f = f + b'/' # False below means "doesn't need to be copied" and can use the # cached value from readsubtree directly. - selflazy[f] = (subpath(f), n, readsubtree, False) + selflazy[f] = (n, readsubtree, False) elif b'/' in f: # This is a flat manifest, so use __setitem__ and setflag rather # than assigning directly to _files and _flags, so we can @@ -1351,7 +1351,7 @@ self._load() flags = self.flags lazydirs = [ - (d[:-1], v[1], b't') for d, v in pycompat.iteritems(self._lazydirs) + (d[:-1], v[0], b't') for d, v in pycompat.iteritems(self._lazydirs) ] dirs = [(d[:-1], self._dirs[d]._node, b't') for d in self._dirs] files = [(f, self._files[f], flags(f)) for f in self._files] @@ -1373,7 +1373,7 @@ def getnode(m, d): ld = m._lazydirs.get(d) if ld: - return ld[1] + return ld[0] return m._dirs.get(d, emptytree)._node # let's skip investigating things that `match` says we do not need.