Patchwork [5,of,5] lazymanifest: add iterkeys() method

login
register
mail settings
Submitter Martin von Zweigbergk
Date March 11, 2015, 11:14 p.m.
Message ID <ecd3a805cd726220e72d.1426115667@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/8010/
State Superseded
Commit 2b7ab29627fd93ca7f5cb838403c2f6c728469bd
Headers show

Comments

Martin von Zweigbergk - March 11, 2015, 11:14 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1426106775 25200
#      Wed Mar 11 13:46:15 2015 -0700
# Node ID ecd3a805cd726220e72dd1c46c7d3a1878cebc8b
# Parent  d503a9f83866a27df8f88fbd8ea1297d8dfc3327
lazymanifest: add iterkeys() method

So we don't have to iteratate over (path, node, flags) tuples only to
throw away the node and flags.

Patch

diff -r d503a9f83866 -r ecd3a805cd72 mercurial/manifest.c
--- a/mercurial/manifest.c	Wed Mar 11 13:15:26 2015 -0700
+++ b/mercurial/manifest.c	Wed Mar 11 13:46:15 2015 -0700
@@ -292,6 +292,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)
@@ -313,6 +357,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)
@@ -790,6 +853,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,
diff -r d503a9f83866 -r ecd3a805cd72 mercurial/manifest.py
--- 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()