Rev 4698: implement slicing as a tuple thunk. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-memory-consumption

John Arbash Meinel john at arbash-meinel.com
Thu Sep 10 20:14:25 BST 2009


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

------------------------------------------------------------
revno: 4698
revision-id: john at arbash-meinel.com-20090910191407-ig2769a7dvbwfzva
parent: john at arbash-meinel.com-20090910183623-16o54sfp451bpeln
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-memory-consumption
timestamp: Thu 2009-09-10 14:14:07 -0500
message:
  implement slicing as a tuple thunk.
  Clean up a few internals that was causing problems.
  It seems that btree requires slicing. We should probably
  implement it directly, depending on what we need.
  
  It is also possible now for the internal extract_key to use
  a Key object, rather than a tuple.
-------------- next part --------------
=== modified file 'bzrlib/_btree_serializer_pyx.pyx'
--- a/bzrlib/_btree_serializer_pyx.pyx	2009-09-10 17:28:10 +0000
+++ b/bzrlib/_btree_serializer_pyx.pyx	2009-09-10 19:14:07 +0000
@@ -169,7 +169,7 @@
             self._start = temp_ptr + 1
             Py_INCREF(key_element)
             PyTuple_SET_ITEM(key, loop_counter, key_element)
-        return key
+        return _keys_type_c.Key(*key)
 
     cdef int process_line(self) except -1:
         """Process a line in the bytes."""

=== modified file 'bzrlib/_keys_type_c.c'
--- a/bzrlib/_keys_type_c.c	2009-09-10 18:36:23 +0000
+++ b/bzrlib/_keys_type_c.c	2009-09-10 19:14:07 +0000
@@ -119,6 +119,9 @@
         return NULL;
     }
     self = (Key *)(type->tp_alloc(type, len));
+    if (self == NULL) {
+        return NULL;
+    }
     self->ob_size = len;
     for (i = 0; i < len; ++i) {
         obj = PyTuple_GET_ITEM(args, i);
@@ -169,31 +172,39 @@
 {
     PyObject *vt, *wt;
     PyObject *vt_to_decref = NULL, *wt_to_decref = NULL;
-    PyObject *result;
+    PyObject *result = NULL;
     
     if (Key_CheckExact(v)) {
         vt = Key_as_tuple((Key *)v);
+        if (vt == NULL) {
+            goto Done;
+        }
         vt_to_decref = vt;
     } else if (PyTuple_Check(v)) {
         vt = v;
         vt_to_decref = NULL;
     } else {
         Py_INCREF(Py_NotImplemented);
-        return Py_NotImplemented;
+        result = Py_NotImplemented;
+        goto Done;
     }
     if (Key_CheckExact(w)) {
         wt = Key_as_tuple((Key *)w);
+        if (wt == NULL) {
+            goto Done;
+        }
         wt_to_decref = wt;
     } else if (PyTuple_Check(w)) {
         wt = w;
         wt_to_decref = NULL;
     } else {
-        Py_XDECREF(vt_to_decref);
         Py_INCREF(Py_NotImplemented);
-        return Py_NotImplemented;
+        result = Py_NotImplemented;
+        goto Done;
     }
     /* Now we have 2 tuples to compare, do it */
     result = PyTuple_Type.tp_richcompare(vt, wt, op);
+Done:
     Py_XDECREF(vt_to_decref);
     Py_XDECREF(wt_to_decref);
     return result;
@@ -209,7 +220,7 @@
 Key_item(Key *self, Py_ssize_t offset)
 {
     PyObject *obj;
-    if (offset < 0 || offset > self->ob_size) {
+    if (offset < 0 || offset >= self->ob_size) {
         PyErr_SetString(PyExc_IndexError, "Key index out of range");
         return NULL;
     }
@@ -218,6 +229,20 @@
     return obj;
 }
 
+static PyObject *
+Key_slice(Key *self, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+    PyObject *as_tuple, *result;
+
+    as_tuple = Key_as_tuple(self);
+    if (as_tuple == NULL) {
+        return NULL;
+    }
+    result = PyTuple_Type.tp_as_sequence->sq_slice(as_tuple, ilow, ihigh);
+    Py_DECREF(as_tuple);
+    return result;
+}
+
 static char Key_doc[] =
     "C implementation of a Key structure."
     "\n This is used as Key(key_bit_1, key_bit_2, key_bit_3, ...)"
@@ -234,7 +259,7 @@
     0,                              /* sq_concat */
     0,                              /* sq_repeat */
     (ssizeargfunc)Key_item,         /* sq_item */
-    0,                              /* sq_slice */
+    (ssizessizeargfunc)Key_slice,   /* sq_slice */
     0,                              /* sq_ass_item */
     0,                              /* sq_ass_slice */
     0,                              /* sq_contains */
@@ -390,6 +415,9 @@
         return NULL;
     }
     self = (Keys *)(type->tp_alloc(type, num_key_bits));
+    if (self == NULL) {
+        return NULL;
+    }
     // self->key_width = (unsigned char)key_width;
     // self->num_keys = (unsigned char)num_keys;
     Keys_set_info(self, key_width, num_keys, flags);
@@ -454,31 +482,39 @@
 {
     PyObject *vt, *wt;
     PyObject *vt_to_decref = NULL, *wt_to_decref = NULL;
-    PyObject *result;
+    PyObject *result = NULL;
     
     if (Keys_CheckExact(v)) {
         vt = Keys_as_tuple((Keys *)v);
+        if (vt == NULL) {
+            goto Done;
+        }
         vt_to_decref = vt;
     } else if (PyTuple_Check(v)) {
         vt = v;
         vt_to_decref = NULL;
     } else {
         Py_INCREF(Py_NotImplemented);
-        return Py_NotImplemented;
+        result = Py_NotImplemented;
+        goto Done;
     }
     if (Keys_CheckExact(w)) {
         wt = Keys_as_tuple((Keys *)w);
+        if (wt == NULL) {
+            goto Done;
+        }
         wt_to_decref = wt;
     } else if (PyTuple_Check(w)) {
         wt = w;
         wt_to_decref = NULL;
     } else {
-        Py_XDECREF(vt_to_decref);
         Py_INCREF(Py_NotImplemented);
-        return Py_NotImplemented;
+        result = Py_NotImplemented;
+        goto Done;
     }
     /* Now we have 2 tuples to compare, do it */
     result = PyTuple_Type.tp_richcompare(vt, wt, op);
+Done:
     Py_XDECREF(vt_to_decref);
     Py_XDECREF(wt_to_decref);
     return result;

=== modified file 'bzrlib/tests/test__keys_type.py'
--- a/bzrlib/tests/test__keys_type.py	2009-09-10 18:36:23 +0000
+++ b/bzrlib/tests/test__keys_type.py	2009-09-10 19:14:07 +0000
@@ -158,6 +158,11 @@
         x[as_tuple] = 'bar'
         self.assertEqual({as_tuple: 'bar'}, x)
 
+    def test_slice(self):
+        k = self.module.Key('foo', 'bar', 'baz', 'bing')
+        self.assertEqual(('foo', 'bar'), k[:2])
+        self.assertEqual(('baz',), k[2:-1])
+
 
 class TestKeysType(tests.TestCase):
 



More information about the bazaar-commits mailing list