D4120: shortest: use nodetree for finding shortest node within revset

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Fri Aug 10 00:26:42 EDT 2018


martinvonz updated this revision to Diff 10275.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4120?vs=10274&id=10275

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

AFFECTED FILES
  mercurial/cext/revlog.c
  mercurial/scmutil.py

CHANGE DETAILS

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -34,6 +34,7 @@
     obsutil,
     pathutil,
     phases,
+    policy,
     pycompat,
     revsetlang,
     similar,
@@ -52,6 +53,8 @@
 else:
     from . import scmposix as scmplatform
 
+parsers = policy.importmod(r'parsers')
+
 termsize = scmplatform.termsize
 
 class status(tuple):
@@ -514,6 +517,24 @@
                 cache['disambiguationrevset'] = revs
         if cl.rev(node) in revs:
             hexnode = hex(node)
+            nodetree = None
+            if cache is not None:
+                nodetree = cache.get('disambiguationnodetree')
+            if not nodetree:
+                try:
+                    nodetree = parsers.nodetree(cl.index, len(revs))
+                except AttributeError:
+                    # no native nodetree
+                    pass
+                else:
+                    for r in revs:
+                        nodetree.insert(r)
+                    if cache is not None:
+                        cache['disambiguationnodetree'] = nodetree
+            if nodetree is not None:
+                length = max(nodetree.shortest(node), minlength)
+                prefix = hexnode[:length]
+                return disambiguate(prefix)
             for length in range(minlength, len(hexnode) + 1):
                 matches = []
                 prefix = hexnode[:length]
diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -1087,6 +1087,23 @@
 	return -1;
 }
 
+static PyObject *nt_insert_py(nodetree *self, PyObject *args)
+{
+	Py_ssize_t rev;
+	const char *node;
+	if (!PyArg_ParseTuple(args, "i", &rev))
+		return NULL;
+	const Py_ssize_t length = index_length(self->index);
+	if (rev < 0 || rev >= length) {
+		PyErr_SetString(PyExc_ValueError, "revlog index out of range");
+		return NULL;
+	}
+	node = index_node_existing(self->index, rev);
+	if (nt_insert(self, node, rev) == -1)
+		return NULL;
+	Py_RETURN_NONE;
+}
+
 static int nt_delete_node(nodetree *self, const char *node)
 {
 	/* rev==-2 happens to get encoded as 0, which is interpreted as not set */
@@ -1118,11 +1135,13 @@
 	return 0;
 }
 
+static PyTypeObject indexType;
+
 static int nt_init_py(nodetree *self, PyObject *args)
 {
-	PyObject *index;
+  indexObject *index;
 	unsigned capacity;
-	if (!PyArg_ParseTuple(args, "O!I", &index, &capacity))
+	if (!PyArg_ParseTuple(args, "O!I", &indexType, &index, &capacity))
 		return -1;
 	return nt_init(self, (indexObject*)index, capacity);
 }
@@ -1179,14 +1198,43 @@
 	return -3;
 }
 
+static PyObject *nt_shortest_py(nodetree *self, PyObject *args)
+{
+	PyObject *val;
+	char *node;
+	int length;
+
+	if (!PyArg_ParseTuple(args, "O", &val))
+		return NULL;
+	if (node_check(val, &node) == -1)
+		return NULL;
+
+	length = nt_shortest(self, node);
+	if (length == -3)
+		return NULL;
+	if (length == -2) {
+		raise_revlog_error();
+		return NULL;
+	}
+	return PyInt_FromLong(length);
+}
+
 static void nt_dealloc(nodetree *self)
 {
 	Py_XDECREF(self->index);
 	free(self->nodes);
 	self->nodes = NULL;
 	PyObject_Del(self);
 }
 
+static PyMethodDef nt_methods[] = {
+	{"insert", (PyCFunction)nt_insert_py, METH_VARARGS,
+	 "insert an index entry"},
+	{"shortest", (PyCFunction)nt_shortest_py, METH_VARARGS,
+	 "find length of shortest hex nodeid of a binary ID"},
+	{NULL} /* Sentinel */
+};
+
 static PyTypeObject nodetreeType = {
 	PyVarObject_HEAD_INIT(NULL, 0) /* header */
 	"parsers.nodetree",        /* tp_name */
@@ -1215,7 +1263,7 @@
 	0,                         /* tp_weaklistoffset */
 	0,                         /* tp_iter */
 	0,                         /* tp_iternext */
-	0,                         /* tp_methods */
+	nt_methods,                /* tp_methods */
 	0,                         /* tp_members */
 	0,                         /* tp_getset */
 	0,                         /* tp_base */



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list