changeset 24295:2b7ab29627fd

lazymanifest: add iterkeys() method So we don't have to iteratate over (path, node, flags) tuples only to throw away the node and flags.
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 11 Mar 2015 13:46:15 -0700
parents 3d485727e45e
children 0178f500d61e
files mercurial/manifest.c mercurial/manifest.py
diffstat 2 files changed, 71 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/manifest.c	Wed Mar 11 13:15:26 2015 -0700
+++ b/mercurial/manifest.c	Wed Mar 11 13:46:15 2015 -0700
@@ -294,6 +294,50 @@
 	lmiter_iternext,                 /* tp_iternext: next() method */
 };
 
+static PyObject *lmiter_iterkeysnext(PyObject *o)
+{
+	size_t pl;
+	line *l = lmiter_nextline((lmIter *)o);
+	if (!l) {
+		return NULL;
+	}
+	pl = pathlen(l);
+	return PyString_FromStringAndSize(l->start, pl);
+}
+
+static PyTypeObject lazymanifestKeysIterator = {
+	PyObject_HEAD_INIT(NULL)
+	0,                               /*ob_size */
+	"parsers.lazymanifest.keysiterator", /*tp_name */
+	sizeof(lmIter),                  /*tp_basicsize */
+	0,                               /*tp_itemsize */
+	lmiter_dealloc,                  /*tp_dealloc */
+	0,                               /*tp_print */
+	0,                               /*tp_getattr */
+	0,                               /*tp_setattr */
+	0,                               /*tp_compare */
+	0,                               /*tp_repr */
+	0,                               /*tp_as_number */
+	0,                               /*tp_as_sequence */
+	0,                               /*tp_as_mapping */
+	0,                               /*tp_hash */
+	0,                               /*tp_call */
+	0,                               /*tp_str */
+	0,                               /*tp_getattro */
+	0,                               /*tp_setattro */
+	0,                               /*tp_as_buffer */
+	/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
+	   use tp_iter and tp_iternext fields. */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
+	"Keys iterator for a lazymanifest.",  /* tp_doc */
+	0,                               /* tp_traverse */
+	0,                               /* tp_clear */
+	0,                               /* tp_richcompare */
+	0,                               /* tp_weaklistoffset */
+	PyObject_SelfIter,               /* tp_iter: __iter__() method */
+	lmiter_iterkeysnext,             /* tp_iternext: next() method */
+};
+
 static lazymanifest *lazymanifest_copy(lazymanifest *self);
 
 static PyObject *lazymanifest_getiter(lazymanifest *self)
@@ -315,6 +359,25 @@
 	return (PyObject *)i;
 }
 
+static PyObject *lazymanifest_getkeysiter(lazymanifest *self)
+{
+	lmIter *i = NULL;
+	lazymanifest *t = lazymanifest_copy(self);
+	if (!t) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+	i = PyObject_New(lmIter, &lazymanifestKeysIterator);
+	if (i) {
+		i->m = t;
+		i->pos = -1;
+	} else {
+		Py_DECREF(t);
+		PyErr_NoMemory();
+	}
+	return (PyObject *)i;
+}
+
 /* __getitem__ and __setitem__ support */
 
 static Py_ssize_t lazymanifest_size(lazymanifest *self)
@@ -795,6 +858,8 @@
 }
 
 static PyMethodDef lazymanifest_methods[] = {
+	{"iterkeys", (PyCFunction)lazymanifest_getkeysiter, METH_NOARGS,
+	 "Iterate over file names in this lazymanifest."},
 	{"copy", (PyCFunction)lazymanifest_copy, METH_NOARGS,
 	 "Make a copy of this lazymanifest."},
 	{"filtercopy", (PyCFunction)lazymanifest_filtercopy, METH_O,
--- a/mercurial/manifest.py	Wed Mar 11 13:15:26 2015 -0700
+++ b/mercurial/manifest.py	Wed Mar 11 13:46:15 2015 -0700
@@ -115,11 +115,14 @@
     def __delitem__(self, key):
         del self._lm[key]
 
-    def keys(self):
-        return [x[0] for x in self._lm]
+    def __iter__(self):
+        return self._lm.iterkeys()
 
     def iterkeys(self):
-        return iter(self.keys())
+        return self._lm.iterkeys()
+
+    def keys(self):
+        return list(self.iterkeys())
 
     def intersectfiles(self, files):
         '''make a new lazymanifest with the intersection of self with files
@@ -184,9 +187,6 @@
         except KeyError:
             return default
 
-    def __iter__(self):
-        return (x[0] for x in self._lm)
-
     def copy(self):
         c = manifestdict('')
         c._lm = self._lm.copy()