Patchwork D11330: dirstate-item: add dedicated "legacy" constructor for `addfile` case

login
register
mail settings
Submitter phabricator
Date Aug. 21, 2021, 9:57 a.m.
Message ID <differential-rev-PHID-DREV-wms5frrs5lg5i77jxwpp-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49646/
State Superseded
Headers show

Comments

phabricator - Aug. 21, 2021, 9:57 a.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This way the internal details of how a DirstateItem is encoded is encapsulated
  within the DirstateItem. This will finally give use some latitude to change the
  data we store in a DirstateItem.
  
  The addfile logic will likely be rewritten eventually and these dedicated
  constructor can be removed at that time.
  
  In the mean-time this should help with hiding internal details of DirstateItem
  and to migrate it to new internal storage and logic.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/cext/parsers.c
  mercurial/dirstatemap.py
  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
@@ -119,6 +119,73 @@ 
             assert False, 'unreachable'
 
     @classmethod
+    def new_added(cls):
+        """constructor to help legacy API to build a new "added" item
+
+        Should eventually be removed
+        """
+        instance = cls()
+        instance._state = b'a'
+        instance._mode = 0
+        instance._size = NONNORMAL
+        instance._mtime = AMBIGUOUS_TIME
+        return instance
+
+    @classmethod
+    def new_merged(cls):
+        """constructor to help legacy API to build a new "merged" item
+
+        Should eventually be removed
+        """
+        instance = cls()
+        instance._state = b'm'
+        instance._mode = 0
+        instance._size = FROM_P2
+        instance._mtime = AMBIGUOUS_TIME
+        return instance
+
+    @classmethod
+    def new_from_p2(cls):
+        """constructor to help legacy API to build a new "from_p2" item
+
+        Should eventually be removed
+        """
+        instance = cls()
+        instance._state = b'n'
+        instance._mode = 0
+        instance._size = FROM_P2
+        instance._mtime = AMBIGUOUS_TIME
+        return instance
+
+    @classmethod
+    def new_possibly_dirty(cls):
+        """constructor to help legacy API to build a new "possibly_dirty" item
+
+        Should eventually be removed
+        """
+        instance = cls()
+        instance._state = b'n'
+        instance._mode = 0
+        instance._size = NONNORMAL
+        instance._mtime = AMBIGUOUS_TIME
+        return instance
+
+    @classmethod
+    def new_normal(cls, mode, size, mtime):
+        """constructor to help legacy API to build a new "normal" item
+
+        Should eventually be removed
+        """
+        assert size != FROM_P2
+        assert size != NONNORMAL
+        instance = cls()
+        instance._state = b'n'
+        instance._mode = mode
+        instance._size = size
+        instance._mtime = mtime
+        return instance
+
+    @classmethod
     def from_v1_data(cls, state, mode, size, mtime):
         """Build a new DirstateItem object from V1 data
 
diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py
--- a/mercurial/dirstatemap.py
+++ b/mercurial/dirstatemap.py
@@ -188,42 +188,28 @@ 
             assert not merged
             assert not possibly_dirty
             assert not from_p2
-            state = b'a'
-            size = NONNORMAL
-            mtime = AMBIGUOUS_TIME
+            new_entry = DirstateItem.new_added()
         elif merged:
             assert not possibly_dirty
             assert not from_p2
-            state = b'm'
-            size = FROM_P2
-            mtime = AMBIGUOUS_TIME
+            new_entry = DirstateItem.new_merged()
         elif from_p2:
             assert not possibly_dirty
-            state = b'n'
-            size = FROM_P2
-            mtime = AMBIGUOUS_TIME
+            new_entry = DirstateItem.new_from_p2()
         elif possibly_dirty:
-            state = b'n'
-            size = NONNORMAL
-            mtime = AMBIGUOUS_TIME
+            new_entry = DirstateItem.new_possibly_dirty()
         else:
-            assert size != FROM_P2
-            assert size != NONNORMAL
             assert size is not None
             assert mtime is not None
-
-            state = b'n'
             size = size & rangemask
             mtime = mtime & rangemask
-        assert state is not None
-        assert size is not None
-        assert mtime is not None
+            new_entry = DirstateItem.new_normal(mode, size, mtime)
         old_entry = self.get(f)
         self._dirs_incr(f, old_entry)
-        e = self._map[f] = DirstateItem.from_v1_data(state, mode, size, mtime)
-        if e.dm_nonnormal:
+        self._map[f] = new_entry
+        if new_entry.dm_nonnormal:
             self.nonnormalset.add(f)
-        if e.dm_otherparent:
+        if new_entry.dm_otherparent:
             self.otherparentset.add(f)
 
     def reset_state(
diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -277,6 +277,102 @@ 
 	return (PyObject *)t;
 };
 
+/* constructor to help legacy API to build a new "added" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_added(PyTypeObject *subtype)
+{
+	dirstateItemObject *t;
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = 'a';
+	t->mode = 0;
+	t->size = dirstate_v1_nonnormal;
+	t->mtime = ambiguous_time;
+	return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "merged" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_merged(PyTypeObject *subtype)
+{
+	dirstateItemObject *t;
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = 'm';
+	t->mode = 0;
+	t->size = dirstate_v1_from_p2;
+	t->mtime = ambiguous_time;
+	return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "from_p2" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_from_p2(PyTypeObject *subtype)
+{
+	/* We do all the initialization here and not a tp_init function because
+	 * dirstate_item is immutable. */
+	dirstateItemObject *t;
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = 'n';
+	t->mode = 0;
+	t->size = dirstate_v1_from_p2;
+	t->mtime = ambiguous_time;
+	return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "possibly" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_possibly_dirty(PyTypeObject *subtype)
+{
+	/* We do all the initialization here and not a tp_init function because
+	 * dirstate_item is immutable. */
+	dirstateItemObject *t;
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = 'n';
+	t->mode = 0;
+	t->size = dirstate_v1_nonnormal;
+	t->mtime = ambiguous_time;
+	return (PyObject *)t;
+};
+
+/* constructor to help legacy API to build a new "normal" item
+
+Should eventually be removed */
+static PyObject *dirstate_item_new_normal(PyTypeObject *subtype, PyObject *args)
+{
+	/* We do all the initialization here and not a tp_init function because
+	 * dirstate_item is immutable. */
+	dirstateItemObject *t;
+	int size, mode, mtime;
+	if (!PyArg_ParseTuple(args, "iii", &mode, &size, &mtime)) {
+		return NULL;
+	}
+
+	t = (dirstateItemObject *)subtype->tp_alloc(subtype, 1);
+	if (!t) {
+		return NULL;
+	}
+	t->state = 'n';
+	t->mode = mode;
+	t->size = size;
+	t->mtime = mtime;
+	return (PyObject *)t;
+};
+
 /* This means the next status call will have to actually check its content
    to make sure it is correct. */
 static PyObject *dirstate_item_set_possibly_dirty(dirstateItemObject *self)
@@ -313,6 +409,21 @@ 
      "True if the stored mtime would be ambiguous with the current time"},
     {"from_v1_data", (PyCFunction)dirstate_item_from_v1_meth,
      METH_VARARGS | METH_CLASS, "build a new DirstateItem object from V1 data"},
+    {"new_added", (PyCFunction)dirstate_item_new_added,
+     METH_NOARGS | METH_CLASS,
+     "constructor to help legacy API to build a new \"added\" item"},
+    {"new_merged", (PyCFunction)dirstate_item_new_merged,
+     METH_NOARGS | METH_CLASS,
+     "constructor to help legacy API to build a new \"merged\" item"},
+    {"new_from_p2", (PyCFunction)dirstate_item_new_from_p2,
+     METH_NOARGS | METH_CLASS,
+     "constructor to help legacy API to build a new \"from_p2\" item"},
+    {"new_possibly_dirty", (PyCFunction)dirstate_item_new_possibly_dirty,
+     METH_NOARGS | METH_CLASS,
+     "constructor to help legacy API to build a new \"possibly_dirty\" item"},
+    {"new_normal", (PyCFunction)dirstate_item_new_normal,
+     METH_VARARGS | METH_CLASS,
+     "constructor to help legacy API to build a new \"normal\" item"},
     {"set_possibly_dirty", (PyCFunction)dirstate_item_set_possibly_dirty,
      METH_NOARGS, "mark a file as \"possibly dirty\""},
     {"set_untracked", (PyCFunction)dirstate_item_set_untracked, METH_NOARGS,