Patchwork D1769: cext: use dedicated type for index entries

login
register
mail settings
Submitter phabricator
Date Jan. 6, 2018, 8:26 a.m.
Message ID <89b6767f3036084cbeccc199e08ab9cb@localhost.localdomain>
Download mbox | patch
Permalink /patch/26588/
State Not Applicable
Headers show

Comments

phabricator - Jan. 6, 2018, 8:26 a.m.
indygreg updated this revision to Diff 4738.
indygreg edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1769?vs=4630&id=4738

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

AFFECTED FILES
  mercurial/cext/parsers.c
  mercurial/cext/revlog.c
  mercurial/policy.py

CHANGE DETAILS




To: indygreg, #hg-reviewers, yuja
Cc: yuja, mercurial-devel

Patch

diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -75,7 +75,7 @@ 
     (r'cext', r'diffhelpers'): 1,
     (r'cext', r'mpatch'): 1,
     (r'cext', r'osutil'): 3,
-    (r'cext', r'parsers'): 5,
+    (r'cext', r'parsers'): 6,
 }
 
 # map import request to other package or module
diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -133,10 +133,22 @@ 
 				    int *ps, int maxrev)
 {
 	if (rev >= self->length - 1) {
-		PyObject *tuple = PyList_GET_ITEM(self->added,
+		PyObject *value;
+		PyObject *entry = PyList_GET_ITEM(self->added,
 						  rev - self->length + 1);
-		ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5));
-		ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6));
+		value = PyObject_GetAttrString(entry, "p1rev");
+		if (!value) {
+			return -1;
+		}
+		ps[0] = (int)PyInt_AS_LONG(value);
+		Py_DECREF(value);
+
+		value = PyObject_GetAttrString(entry, "p2rev");
+		if (!value) {
+			return -1;
+		}
+		ps[1] = (int)PyInt_AS_LONG(value);
+		Py_DECREF(value);
 	} else {
 		const char *data = index_deref(self, rev);
 		ps[0] = getbe32(data + 24);
@@ -224,9 +236,9 @@ 
 	parent_2 = getbe32(data + 28);
 	c_node_id = data + 32;
 
-	entry = Py_BuildValue(index_entry_format, offset_flags, comp_len,
-			      uncomp_len, base_rev, link_rev,
-			      parent_1, parent_2, c_node_id, 20);
+	entry = PyObject_CallFunction(self->entrytype, index_entry_format,
+			    offset_flags, comp_len, uncomp_len, base_rev,
+			    link_rev, parent_1, parent_2, c_node_id, 20);
 
 	if (entry) {
 		PyObject_GC_UnTrack(entry);
@@ -253,10 +265,16 @@ 
 		return NULL;
 
 	if (pos >= self->length - 1) {
-		PyObject *tuple, *str;
-		tuple = PyList_GET_ITEM(self->added, pos - self->length + 1);
-		str = PyTuple_GetItem(tuple, 7);
-		return str ? PyBytes_AS_STRING(str) : NULL;
+		PyObject *entry, *str;
+		char *result;
+		entry = PyList_GET_ITEM(self->added, pos - self->length + 1);
+		str = PyObject_GetAttrString(entry, "node");
+		if (!str) {
+			return NULL;
+		}
+		result = PyBytes_AS_STRING(str);
+		Py_DECREF(str);
+		return result;
 	}
 
 	data = index_deref(self, pos);
@@ -277,21 +295,46 @@ 
 
 static PyObject *index_insert(indexObject *self, PyObject *args)
 {
-	PyObject *obj;
+	PyObject *obj, *nodeobj;
+	PyObject *result = NULL;
+	PyObject *tmpobj = NULL;
 	char *node;
 	int index;
 	Py_ssize_t len, nodelen;
 
 	if (!PyArg_ParseTuple(args, "iO", &index, &obj))
 		return NULL;
 
-	if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) {
-		PyErr_SetString(PyExc_TypeError, "8-tuple required");
-		return NULL;
+	/* Legacy callers may pass tuples. Convert to an index entry until
+	 * API compatibility is dropped. */
+	if (PyTuple_Check(obj)) {
+		tmpobj = PyObject_Call(self->entrytype, obj, NULL);
+		if (!tmpobj) {
+			return NULL;
+		}
+
+		/* We own a reference to tmpobj. So any return after here
+		   needs to decrease its refcount. */
+		obj = tmpobj;
 	}
 
-	if (node_check(PyTuple_GET_ITEM(obj, 7), &node, &nodelen) == -1)
-		return NULL;
+	if (!PyObject_TypeCheck(obj, (PyTypeObject *)self->entrytype)) {
+		PyErr_SetString(PyExc_TypeError, "IndexV1Entry type required");
+		goto cleanup;
+	}
+
+	nodeobj = PyObject_GetAttrString(obj, "node");
+	if (!nodeobj) {
+		PyErr_SetString(PyExc_ValueError, "could not retrieve node");
+		goto cleanup;
+	}
+	if (node_check(nodeobj, &node, &nodelen) == -1) {
+		Py_DECREF(nodeobj);
+		goto cleanup;
+	}
+
+	Py_DECREF(nodeobj);
+	nodeobj = NULL;
 
 	len = index_length(self);
 
@@ -301,23 +344,30 @@ 
 	if (index != len - 1) {
 		PyErr_SetString(PyExc_IndexError,
 				"insert only supported at index -1");
-		return NULL;
+		goto cleanup;
 	}
 
 	if (self->added == NULL) {
 		self->added = PyList_New(0);
-		if (self->added == NULL)
-			return NULL;
+		if (self->added == NULL) {
+			goto cleanup;
+		}
 	}
 
-	if (PyList_Append(self->added, obj) == -1)
-		return NULL;
+	if (PyList_Append(self->added, obj) == -1) {
+		goto cleanup;
+	}
 
 	if (self->nt)
 		nt_insert(self, node, index);
 
 	Py_CLEAR(self->headrevs);
-	Py_RETURN_NONE;
+	result = Py_None;
+	Py_INCREF(Py_None);
+
+cleanup:
+	Py_XDECREF(tmpobj);
+	return result;
 }
 
 static void _index_clearcaches(indexObject *self)
@@ -837,9 +887,17 @@ 
 	const char *data;
 
 	if (rev >= self->length - 1) {
-		PyObject *tuple = PyList_GET_ITEM(self->added,
+		PyObject *value;
+		int result;
+		PyObject *entry = PyList_GET_ITEM(self->added,
 			rev - self->length + 1);
-		return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3));
+		value = PyObject_GetAttrString(entry, "baserev");
+		if (!value) {
+			return -2;
+		}
+		result = (int)PyInt_AS_LONG(value);
+		Py_DECREF(value);
+		return result;
 	}
 	else {
 		data = index_deref(self, rev);
@@ -1712,10 +1770,14 @@ 
 	Py_ssize_t i, len = PyList_GET_SIZE(self->added);
 
 	for (i = start; i < len; i++) {
-		PyObject *tuple = PyList_GET_ITEM(self->added, i);
-		PyObject *node = PyTuple_GET_ITEM(tuple, 7);
+		PyObject *entry = PyList_GET_ITEM(self->added, i);
+		PyObject *node = PyObject_GetAttrString(entry, "node");
+		if (!node) {
+			return;
+		}
 
 		nt_insert(self, PyBytes_AS_STRING(node), -1);
+		Py_DECREF(node);
 	}
 
 	if (start == 0)
@@ -1895,8 +1957,9 @@ 
 		return -1;
 	}
 
-	self->nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0,
-					-1, -1, -1, -1, nullid, 20);
+	self->nullentry = PyObject_CallFunction(self->entrytype, "iiiiiiis#",
+						0, 0, 0, -1, -1, -1, -1,
+						nullid, 20);
 	if (!self->nullentry) {
 		return -1;
 	}
diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -710,7 +710,7 @@ 
 void manifest_module_init(PyObject *mod);
 void revlog_module_init(PyObject *mod);
 
-static const int version = 5;
+static const int version = 6;
 
 static void module_init(PyObject *mod)
 {