Rev 4696: Implement some of the sequence items. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-memory-consumption

John Arbash Meinel john at arbash-meinel.com
Thu Sep 10 19:28:10 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/2.1-memory-consumption

------------------------------------------------------------
revno: 4696
revision-id: john at arbash-meinel.com-20090910182754-20e7ppaducyrx0yh
parent: john at arbash-meinel.com-20090910181517-hby4nv0dus37pavn
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-memory-consumption
timestamp: Thu 2009-09-10 13:27:54 -0500
message:
  Implement some of the sequence items.
  
  This also revealed that we need to decref during Key_dealloc.
-------------- next part --------------
=== modified file 'bzrlib/_keys_type_c.c'
--- a/bzrlib/_keys_type_c.c	2009-09-10 18:15:17 +0000
+++ b/bzrlib/_keys_type_c.c	2009-09-10 18:27:54 +0000
@@ -83,18 +83,13 @@
 static char Key_as_tuple_doc[] = "as_tuple() => tuple";
 
 static void
-Key_dealloc(Keys *self)
+Key_dealloc(Key *self)
 {
-    // /* Do we want to use the Py_TRASHCAN_SAFE_BEGIN/END operations? */
-    // if (num_keys > 0) {
-    //     /* tuple deallocs from the end to the beginning. Not sure why, but
-    //      * we'll do the same here.
-    //      */
-    //     int i;
-    //     for(i = num_keys - 1; i >= 0; --i) {
-    //         Py_XDECREF(self->key_strings[i]);
-    //     }
-    // }
+    Py_ssize_t i;
+
+    for (i = 0; i < self->ob_size; ++i) {
+        Py_XDECREF(self->key_strings[i]);
+    }
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
@@ -138,6 +133,24 @@
     return (PyObject *)self;
 }
 
+static Py_ssize_t
+Key_length(Key *self)
+{
+    return self->ob_size;
+}
+
+static PyObject *
+Key_item(Key *self, Py_ssize_t offset)
+{
+    PyObject *obj;
+    if (offset < 0 || offset > self->ob_size) {
+        PyErr_SetString(PyExc_IndexError, "Key index out of range");
+        return NULL;
+    }
+    obj = (PyObject *)self->key_strings[offset];
+    Py_INCREF(obj);
+    return obj;
+}
 
 static char Key_doc[] =
     "C implementation of a Key structure."
@@ -150,16 +163,16 @@
     {NULL, NULL} /* sentinel */
 };
 
-// static PySequenceMethods Key_as_sequence = {
-//     (lenfunc)Key_length,            /* sq_length */
-//     0,                              /* sq_concat */
-//     0,                              /* sq_repeat */
-//     (ssizeargfunc)Key_item,         /* sq_item */
-//     0,                              /* sq_slice */
-//     0,                              /* sq_ass_item */
-//     0,                              /* sq_ass_slice */
-//     0,                              /* sq_contains */
-// };
+static PySequenceMethods Key_as_sequence = {
+    (lenfunc)Key_length,            /* sq_length */
+    0,                              /* sq_concat */
+    0,                              /* sq_repeat */
+    (ssizeargfunc)Key_item,         /* sq_item */
+    0,                              /* sq_slice */
+    0,                              /* sq_ass_item */
+    0,                              /* sq_ass_slice */
+    0,                              /* sq_contains */
+};
 
 static PyTypeObject KeyType = {
     PyObject_HEAD_INIT(NULL)
@@ -167,14 +180,14 @@
     "Key",                                       /* tp_name */
     sizeof(Key) - sizeof(PyStringObject *),      /* tp_basicsize */
     sizeof(PyObject *),                          /* tp_itemsize */
-    Key_dealloc,                                 /* tp_dealloc */
+    (destructor)Key_dealloc,                     /* tp_dealloc */
     0,                                           /* tp_print */
     0,                                           /* tp_getattr */
     0,                                           /* tp_setattr */
     0,                                           /* tp_compare */
     0, //(reprfunc)Keys_repr,                         /* tp_repr */
     0,                                           /* tp_as_number */
-    0, //&Keys_as_sequence,                           /* tp_as_sequence */
+    &Key_as_sequence,                            /* tp_as_sequence */
     0,                                           /* tp_as_mapping */
     0, //(hashfunc)Keys_hash,                         /* tp_hash */
     0,                                           /* tp_call */

=== modified file 'bzrlib/tests/test__keys_type.py'
--- a/bzrlib/tests/test__keys_type.py	2009-09-10 18:15:17 +0000
+++ b/bzrlib/tests/test__keys_type.py	2009-09-10 18:27:54 +0000
@@ -87,6 +87,38 @@
             t = k.as_tuple()
         self.assertEqual(('foo', 'bar'), t)
 
+    def test_len(self):
+        k = self.module.Key('foo')
+        self.assertEqual(1, len(k))
+        k = self.module.Key('foo', 'bar')
+        self.assertEqual(2, len(k))
+        k = self.module.Key('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
+        self.assertEqual(7, len(k))
+
+    def test_getitem(self):
+        k = self.module.Key('foo', 'bar', 'b', 'b', 'b', 'b', 'z')
+        self.assertEqual('foo', k[0])
+        self.assertEqual('foo', k[0])
+        self.assertEqual('foo', k[0])
+        self.assertEqual('z', k[6])
+        self.assertEqual('z', k[-1])
+
+    def test_refcount(self):
+        f = 'fo' + 'oo'
+        num_refs = sys.getrefcount(f)
+        k = self.module.Key(f)
+        self.assertEqual(num_refs + 1, sys.getrefcount(f))
+        b = k[0]
+        self.assertEqual(num_refs + 2, sys.getrefcount(f))
+        b = k[0]
+        self.assertEqual(num_refs + 2, sys.getrefcount(f))
+        c = k[0]
+        self.assertEqual(num_refs + 3, sys.getrefcount(f))
+        del b, c
+        self.assertEqual(num_refs + 1, sys.getrefcount(f))
+        del k
+        self.assertEqual(num_refs, sys.getrefcount(f))
+
 
 class TestKeysType(tests.TestCase):
 
@@ -115,7 +147,7 @@
         del k
         self.assertEqual(n_ref, sys.getrefcount(s))
 
-    def test_get_item(self):
+    def test_getitem(self):
         f = 'fo' + 'o'
         k = self.module.Keys(1, f, 'bar')
         self.assertEqual(('foo',), k[0])



More information about the bazaar-commits mailing list