[PATCH 1 of 5 V5] dirstate: rename the dirstate parsing and packing methods

Laurent Charignon lcharignon at fb.com
Thu Dec 17 23:44:42 UTC 2015


# HG changeset patch
# User Laurent Charignon <lcharignon at fb.com>
# Date 1450380353 28800
#      Thu Dec 17 11:25:53 2015 -0800
# Node ID 44eafafb98c9d24bdff7d6c46213ffe2cf8edc8d
# Parent  7e8a883da1711008262150bb6f64131812de3e0b
dirstate: rename the dirstate parsing and packing methods

In this patch series, we are changing the signature and behavior of the
dirstate parsing and packing method. Since these methods are implemented in
Python and C and to ensure backward compatibility, this patch renames the
dirstate packing and packing method.

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -373,6 +373,7 @@ class dirstate(object):
     def _read(self):
         self._map = {}
         self._copymap = {}
+        self._nonnormalmap = {}
         try:
             fp = self._opendirstatefile()
             try:
@@ -401,7 +402,7 @@ class dirstate(object):
 
         # Python's garbage collector triggers a GC each time a certain number
         # of container objects (the number being defined by
-        # gc.get_threshold()) are allocated. parse_dirstate creates a tuple
+        # gc.get_threshold()) are allocated. parse_dirstate_v2 creates a tuple
         # for each file in the dirstate. The C version then immediately marks
         # them as not to be tracked by the collector. However, this has no
         # effect on when GCs are triggered, only on what objects the GC looks
@@ -411,8 +412,8 @@ class dirstate(object):
         # parsing the dirstate.
         #
         # (we cannot decorate the function directly since it is in a C module)
-        parse_dirstate = util.nogc(parsers.parse_dirstate)
-        p = parse_dirstate(self._map, self._copymap, st)
+        parse_dirstate_v2 = util.nogc(parsers.parse_dirstate_v2)
+        p = parse_dirstate_v2(self._map, self._copymap, st, self._nonnormalmap)
         if not self._dirtypl:
             self._pl = p
 
@@ -662,7 +663,7 @@ class dirstate(object):
         if not self._dirty:
             return
 
-        # enough 'delaywrite' prevents 'pack_dirstate' from dropping
+        # enough 'delaywrite' prevents 'pack_dirstate_v2' from dropping
         # timestamp of each entries in dirstate, because of 'now > mtime'
         delaywrite = self._ui.configint('debug', 'dirstate.delaywrite', 0)
         if delaywrite > 0:
@@ -688,7 +689,7 @@ class dirstate(object):
             # See also the wiki page below for detail:
             # https://www.mercurial-scm.org/wiki/DirstateTransactionPlan
 
-            # emulate dropping timestamp in 'parsers.pack_dirstate'
+            # emulate dropping timestamp in 'parsers.pack_dirstate_v2'
             now = _getfsnow(self._opener)
             dmap = self._map
             for f, e in dmap.iteritems():
@@ -710,7 +711,8 @@ class dirstate(object):
         # use the modification time of the newly created temporary file as the
         # filesystem's notion of 'now'
         now = util.fstat(st).st_mtime & _rangemask
-        st.write(parsers.pack_dirstate(self._map, self._copymap, self._pl, now))
+        st.write(parsers.pack_dirstate_v2(self._map, self._copymap, self._pl,
+                                          now, self._nonnormalmap))
         st.close()
         self._lastnormaltime = 0
         self._dirty = self._dirtypl = False
diff --git a/mercurial/parsers.c b/mercurial/parsers.c
--- a/mercurial/parsers.c
+++ b/mercurial/parsers.c
@@ -463,19 +463,19 @@ PyTypeObject dirstateTupleType = {
 	dirstate_tuple_new,        /* tp_new */
 };
 
-static PyObject *parse_dirstate(PyObject *self, PyObject *args)
 {
-	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
+static PyObject *parse_dirstate_v2(PyObject *self, PyObject *args)
+	PyObject *dmap, *cmap, *nonnmap, *parents = NULL, *ret = NULL;
 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
 	char state, *cur, *str, *cpos;
 	int mode, size, mtime;
 	unsigned int flen, len, pos = 40;
 	int readlen;
 
-	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
+	if (!PyArg_ParseTuple(args, "O!O!s#O!:parse_dirstate_v2",
 			      &PyDict_Type, &dmap,
 			      &PyDict_Type, &cmap,
-			      &str, &readlen))
+			      &str, &readlen, &PyDict_Type, &nonnmap))
 		goto quit;
 
 	len = readlen;
@@ -549,18 +549,18 @@ quit:
 /*
  * Efficiently pack a dirstate object into its on-disk format.
  */
-static PyObject *pack_dirstate(PyObject *self, PyObject *args)
+static PyObject *pack_dirstate_v2(PyObject *self, PyObject *args)
 {
 	PyObject *packobj = NULL;
-	PyObject *map, *copymap, *pl, *mtime_unset = NULL;
+	PyObject *map, *copymap, *nonnmap, *pl, *mtime_unset = NULL;
 	Py_ssize_t nbytes, pos, l;
 	PyObject *k, *v = NULL, *pn;
 	char *p, *s;
 	int now;
 
-	if (!PyArg_ParseTuple(args, "O!O!Oi:pack_dirstate",
+	if (!PyArg_ParseTuple(args, "O!O!OiO!:pack_dirstate_v2",
 			      &PyDict_Type, &map, &PyDict_Type, &copymap,
-			      &pl, &now))
+			      &pl, &now, &PyDict_Type, &nonnmap))
 		return NULL;
 
 	if (!PySequence_Check(pl) || PySequence_Size(pl) != 2) {
@@ -2747,9 +2747,9 @@ PyObject *pathencode(PyObject *self, PyO
 PyObject *lowerencode(PyObject *self, PyObject *args);
 
 static PyMethodDef methods[] = {
-	{"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"},
+	{"pack_dirstate_v2", pack_dirstate_v2, METH_VARARGS, "pack a dirstate\n"},
 	{"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
-	{"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
+	{"parse_dirstate_v2", parse_dirstate_v2, METH_VARARGS, "parse a dirstate\n"},
 	{"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"},
 	{"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"},
 	{"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"},
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -68,7 +68,7 @@ def parse_index2(data, inline):
 
     return index, cache
 
-def parse_dirstate(dmap, copymap, st):
+def parse_dirstate_v2(dmap, copymap, st, nonnormalmap=None):
     parents = [st[:20], st[20: 40]]
     # dereference fields so they will be local in loop
     format = ">cllll"
@@ -88,7 +88,7 @@ def parse_dirstate(dmap, copymap, st):
         dmap[f] = e[:4]
     return parents
 
-def pack_dirstate(dmap, copymap, pl, now):
+def pack_dirstate_v2(dmap, copymap, pl, now, nonnormalmap=None):
     now = int(now)
     cs = cStringIO.StringIO()
     write = cs.write
diff --git a/tests/fakedirstatewritetime.py b/tests/fakedirstatewritetime.py
--- a/tests/fakedirstatewritetime.py
+++ b/tests/fakedirstatewritetime.py
@@ -15,8 +15,8 @@ from mercurial import (
     util,
 )
 
-def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
-    # execute what original parsers.pack_dirstate should do actually
+def pack_dirstate(fakenow, orig, dmap, copymap, pl, now, nonnormalmap):
+    # execute what original parsers.pack_dirstate_v2 should do actually
     # for consistency
     actualnow = int(now)
     for f, e in dmap.iteritems():
@@ -24,16 +24,16 @@ def pack_dirstate(fakenow, orig, dmap, c
             e = parsers.dirstatetuple(e[0], e[1], e[2], -1)
             dmap[f] = e
 
-    return orig(dmap, copymap, pl, fakenow)
+    return orig(dmap, copymap, pl, fakenow, nonnormalmap)
 
 def fakewrite(ui, func):
-    # fake "now" of 'pack_dirstate' only if it is invoked while 'func'
+    # fake "now" of 'pack_dirstate_v2' only if it is invoked while 'func'
 
     fakenow = ui.config('fakedirstatewritetime', 'fakenow')
     if not fakenow:
         # Execute original one, if fakenow isn't configured. This is
         # useful to prevent subrepos from executing replaced one,
-        # because replacing 'parsers.pack_dirstate' is also effective
+        # because replacing 'parsers.pack_dirstate_v2' is also effective
         # in subrepos.
         return func()
 
@@ -41,16 +41,16 @@ def fakewrite(ui, func):
     # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
     fakenow = util.parsedate(fakenow, ['%Y%m%d%H%M'])[0]
 
-    orig_pack_dirstate = parsers.pack_dirstate
+    orig_pack_dirstate = parsers.pack_dirstate_v2
     orig_dirstate_getfsnow = dirstate._getfsnow
     wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)
 
-    parsers.pack_dirstate = wrapper
+    parsers.pack_dirstate_v2 = wrapper
     dirstate._getfsnow = lambda *args: fakenow
     try:
         return func()
     finally:
-        parsers.pack_dirstate = orig_pack_dirstate
+        parsers.pack_dirstate_v2 = orig_pack_dirstate
         dirstate._getfsnow = orig_dirstate_getfsnow
 
 def _checklookup(orig, workingctx, files):


More information about the Mercurial-devel mailing list