Patchwork [2,of,6] scmutil: add a dirs class

login
register
mail settings
Submitter Bryan O'Sullivan
Date April 1, 2013, 8:49 p.m.
Message ID <eebf8fe7dea5ce3d262f.1364849355@australite.local>
Download mbox | patch
Permalink /patch/1232/
State Accepted, archived
Headers show

Comments

Bryan O'Sullivan - April 1, 2013, 8:49 p.m.
# HG changeset patch
# User Bryan O'Sullivan <bryano@fb.com>
# Date 1364849265 25200
#      Mon Apr 01 13:47:45 2013 -0700
# Node ID eebf8fe7dea5ce3d262f89f848f2024c063b26e4
# Parent  cd42138d63c3110cbcd07b389f1d99920fb031ac
scmutil: add a dirs class

This encapsulates the "bag of directories" structures that are
currently open-coded (and duplicated) in both the dirstate and
context modules.

This will be used, and optionally replaced by a C implementation,
in upcoming changes.
Bryan O'Sullivan - April 11, 2013, 4:18 p.m.
On Thu, Apr 11, 2013 at 8:44 AM, Kevin Bullock <
kbullock+mercurial@ringworld.org> wrote:

> Sorry, I actually have 'it' referring to a different thing than the
> subject of the first clause. It would be helpful for 'm' to have a more
> descriptive name, and for the _class_ to have a docstring as described.
>

Yep, all done.

Patch

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -933,3 +933,37 @@  def finddirs(path):
     while pos != -1:
         yield path[:pos]
         pos = path.rfind('/', 0, pos)
+
+class dirs(object):
+    def __init__(self, m, skip=None):
+        self._dirs = {}
+        addpath = self.addpath
+        if util.safehasattr(m, 'iteritems') and skip is not None:
+            for f, s in m.iteritems():
+                if s[0] != skip:
+                    addpath(f)
+        else:
+            for f in m:
+                addpath(f)
+
+    def addpath(self, path):
+        dirs = self._dirs
+        for base in finddirs(path):
+            if base in dirs:
+                dirs[base] += 1
+                return
+            dirs[base] = 1
+
+    def delpath(self, path):
+        dirs = self._dirs
+        for base in finddirs(path):
+            if dirs[base] > 1:
+                dirs[base] -= 1
+                return
+            del dirs[base]
+
+    def __iter__(self):
+        return self._dirs.iterkeys()
+
+    def __contains__(self, d):
+        return d in self._dirs