Patchwork D11118: dirstate-item: add a `from_v1_data` constructor

login
register
mail settings
Submitter phabricator
Date July 19, 2021, 10:39 a.m.
Message ID <differential-rev-PHID-DREV-eys7azlgsp2s4zeor2b5-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49432/
State Superseded
Headers show

Comments

phabricator - July 19, 2021, 10:39 a.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This class method is dedicated to building a DirstateItem from the data
  available in the "dirstate-v1" format. Since that format is frozen, this
  constructor will never change (unlike the `__init__` one).

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D11118

AFFECTED FILES
  mercurial/cext/parsers.c
  mercurial/pure/parsers.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -67,6 +67,20 @@ 
         self._size = size
         self._mtime = mtime
 
+    @classmethod
+    def from_v1_data(cls, state, mode, size, mtime):
+        """Build a new DirstateItem object from V1 data
+
+        Since the dirstate-v1 format is frozen, the signature of this function
+        is not expected to change, unlike the __init__ one.
+        """
+        return cls(
+            state=state,
+            mode=mode,
+            size=size,
+            mtime=mtime,
+        )
+
     def __getitem__(self, idx):
         if idx == 0 or idx == -4:
             msg = b"do not use item[x], use item.state"
@@ -546,7 +560,7 @@ 
         if b'\0' in f:
             f, c = f.split(b'\0')
             copymap[f] = c
-        dmap[f] = DirstateItem(*e[:4])
+        dmap[f] = DirstateItem.from_v1_data(*e[:4])
     return parents
 
 
diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -155,6 +155,48 @@ 
 	}
 };
 
+/* This will never change since it's bound to V1, unlike `make_dirstate_item`
+ */
+static inline dirstateItemObject *
+dirstate_item_from_v1_data(char state, int mode, int size, int mtime)
+{
+	dirstateItemObject *t =
+	    PyObject_New(dirstateItemObject, &dirstateItemType);
+	if (!t) {
+		return NULL;
+	}
+	t->state = state;
+	t->mode = mode;
+	t->size = size;
+	t->mtime = mtime;
+	return t;
+}
+
+/* This will never change since it's bound to V1, unlike `dirstate_item_new` */
+static PyObject *dirstate_item_from_v1_meth(PyTypeObject *subtype,
+                                            PyObject *args)
+{
+	/* We do all the initialization here and not a tp_init function because
+	 * dirstate_item is immutable. */
+	dirstateItemObject *t;
+	char state;
+	int size, mode, mtime;
+	if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime)) {
+		return NULL;
+	}
+
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = state;
+	t->mode = mode;
+	t->size = size;
+	t->mtime = mtime;
+
+	return (PyObject *)t;
+};
+
 static PyMethodDef dirstate_item_methods[] = {
     {"v1_state", (PyCFunction)dirstate_item_v1_state, METH_NOARGS,
      "return a \"state\" suitable for v1 serialization"},
@@ -166,6 +208,8 @@ 
      "return a \"mtime\" suitable for v1 serialization"},
     {"need_delay", (PyCFunction)dirstate_item_need_delay, METH_O,
      "True if the stored mtime would be ambiguous with the current time"},
+    {"from_v1_data", (PyCFunction)dirstate_item_from_v1_meth, METH_O,
+     "build a new DirstateItem object from V1 data"},
     {NULL} /* Sentinel */
 };
 
@@ -363,8 +407,8 @@ 
 			goto quit;
 		}
 
-		entry =
-		    (PyObject *)make_dirstate_item(state, mode, size, mtime);
+		entry = (PyObject *)dirstate_item_from_v1_data(state, mode,
+		                                               size, mtime);
 		cpos = memchr(cur, 0, flen);
 		if (cpos) {
 			fname = PyBytes_FromStringAndSize(cur, cpos - cur);