Patchwork [2,of,3] treemanifest: refactor treemanifest.walk()

login
register
mail settings
Submitter Drew Gottlieb
Date April 7, 2015, 10:56 p.m.
Message ID <73713a0f0471739a8a91.1428447371@waste.org>
Download mbox | patch
Permalink /patch/8553/
State Accepted
Headers show

Comments

Drew Gottlieb - April 7, 2015, 10:56 p.m.
# HG changeset patch
# User Drew Gottlieb <drgott@google.com>
# Date 1428445132 25200
#      Tue Apr 07 15:18:52 2015 -0700
# Node ID 73713a0f0471739a8a91cda6d7b8966ebf07cdc1
# Parent  8d24c368a96deb93ceda8cd036234186907c4eda
treemanifest: refactor treemanifest.walk()

This refactor is a preparation for an optimization in the next commit. This
introduces a recursive element that recurses each submanifest. By using a
recursive function, the next commit can avoid walking over some subdirectories
altogether.
Matt Mackall - April 7, 2015, 11:16 p.m.
On Tue, 2015-04-07 at 17:56 -0500, Drew Gottlieb wrote:
> # HG changeset patch
> # User Drew Gottlieb <drgott@google.com>
> # Date 1428445132 25200
> #      Tue Apr 07 15:18:52 2015 -0700
> # Node ID 73713a0f0471739a8a91cda6d7b8966ebf07cdc1
> # Parent  8d24c368a96deb93ceda8cd036234186907c4eda
> treemanifest: refactor treemanifest.walk()

These are queued for default, thanks.

Patch

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -623,12 +623,11 @@ 
                     yield fn
                 raise StopIteration
 
-        for fn in self:
+        for fn in self._walk(match):
             if fn in fset:
                 # specified pattern is the exact name
                 fset.remove(fn)
-            if match(fn):
-                yield fn
+            yield fn
 
         # for dirstate.walk, files=['.'] means "walk the whole tree".
         # follow that here, too
@@ -638,6 +637,19 @@ 
             if not self.hasdir(fn):
                 match.bad(fn, None)
 
+    def _walk(self, match):
+        '''Recursively generates matching file names for walk().'''
+
+        # yield this dir's files and walk its submanifests
+        for p in sorted(self._dirs.keys() + self._files.keys()):
+            if p in self._files:
+                fullp = self._subpath(p)
+                if match(fullp):
+                    yield fullp
+            else:
+                for f in self._dirs[p]._walk(match):
+                    yield f
+
     def matches(self, match):
         '''generate a new manifest filtered by the match argument'''
         if match.always():