[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.1.2.15 BucketTemplate.c:1.1.2.16

Tim Peters tim.one@comcast.net
Wed, 5 Jun 2002 21:13:09 -0400


Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv9108

Modified Files:
      Tag: Zope-3x-branch
	BTreeTemplate.c BucketTemplate.c 
Log Message:
Sped and corrected BTree and Bucket gc traversal (in particular, while key
0 in a BTree node isn't legit, child 0 is).

Jeremy, don't these routines need to unghostify?  I also rearranged code
on the bet that they do, but didn't finish that job.

Note that a few of the persistence tests failed with
    AttributeError: Connection instance has no attribute '_storage'
before this patch.  The good news is that they still fail <wink>.


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.1.2.14 => 1.1.2.15 ===
 BTree_traverse(BTree *self, visitproc visit, void *arg)
 {
-    int err, i, l;
+    int err = 0;
+    int i, len;
+    
+    /* XXX doesn't this routine need to unghostify? */
+
+#define VISIT(SLOT)                             \
+    if (SLOT) {                                 \
+        err = visit((PyObject *)(SLOT), arg);   \
+        if (err)                                \
+            goto Error;                         \
+    }
 
     err = PyPersist_BASE_TYPE->tp_traverse((PyObject *)self, visit, arg);
     if (err)
-	return err;
+	goto Error;
 
-#define VISIT(SLOT) \
-    if (SLOT) { \
-	err = visit((PyObject *)(SLOT), arg); \
-	if (err) \
-		     return err; \
+    len = self->len;
+    if (KEY_IF_OBJECT(self) != NULL) {
+        /* Keys are Python objects so need to be traversed.  Note that the
+         * key 0 slot is unused and should not be traversed.
+         */ 
+        for (i = 1 ; i < len; i++)
+	    VISIT(self->data[i].key);
     }
 
-    if (self->firstbucket)
-	VISIT(self->firstbucket);
-    /* The first bucket is garbage.  Don't visit it. */
-    for (i = 1, l = self->len; i < l; i++) {
-	VISIT(KEY_IF_OBJECT(self->data[i].key));
-	VISIT(self->data[i].child);
-    }
-#undef VISIT    
-    return 0;
+    /* Children are always pointers, and child 0 is legit. */
+    for (i = 0; i < len; i++)
+        VISIT(self->data[i].child);
+
+Error:
+    /* XXX I figure an "end persistence dance" probably belongs here */
+    return err;
+
+#undef VISIT
 }
 
 static int


=== Zope3/lib/python/Persistence/BTrees/BucketTemplate.c 1.1.2.15 => 1.1.2.16 === (496/596 lines abridged)
   Copyright (c) 2001, 2002 Zope Corporation and Contributors.
   All Rights Reserved.
-  
+
   This software is subject to the provisions of the Zope Public License,
   Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
   WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
   FOR A PARTICULAR PURPOSE
-  
+
  ****************************************************************************/
 
 #define BUCKETTEMPLATE_C "$Id$\n"
@@ -33,7 +33,7 @@
   int min, max, i, l, cmp, copied=1;
   PyObject *r;
   KEY_TYPE key;
-  
+
   COPY_KEY_FROM_ARG(key, keyarg, copied);
   UNLESS (copied) return NULL;
 
@@ -74,7 +74,7 @@
 {
   return _bucket_get(self, key, 0);
 }
-  
+
 /*
 ** Bucket_grow
 **
@@ -90,7 +90,7 @@
 ** Returns:     -1      on error, and MemoryError exception is set
 **               0      on success
 */
-static int 
+static int
 Bucket_grow(Bucket *self, int newsize, int noval)
 {
     KEY_TYPE *keys;
@@ -103,7 +103,7 @@
             goto Overflow;
         UNLESS (keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE) * newsize))
             return -1;
-    
+
         UNLESS (noval) {
             UNLESS (values = BTree_Realloc(self->values,

[-=- -=- -=- 496 lines omitted -=- -=- -=-]

+        /* self->values exists (this is a mapping bucket, not a set bucket),
+         * and are Python objects, so need to be traversed. */
+        for (i = 0; i < len; i++)
+            VISIT(self->values[i]);
     }
 
+    VISIT(self->next);
+
+Error:
+    /* XXX I figure an "end persistence dance" probably belongs here */
+    return err;
+
 #undef VISIT
-    return 0;
 }
 
 int
@@ -1287,7 +1298,7 @@
     0,					/* tp_getattro */
     0,					/* tp_setattro */
     0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
 	    Py_TPFLAGS_BASETYPE, 	/* tp_flags */
     0,					/* tp_doc */
     (traverseproc)bucket_traverse,	/* tp_traverse */
@@ -1309,13 +1320,13 @@
     PyType_GenericNew,			/* tp_new */
 };
 
-static int 
+static int
 nextBucket(SetIteration *i)
 {
   if (i->position >= 0)
     {
       UNLESS(PER_USE(BUCKET(i->set))) return -1;
-          
+
       if (i->position)
         {
           DECREF_KEY(i->key);
@@ -1339,6 +1350,6 @@
       PyPersist_DECREF(BUCKET(i->set));
     }
 
-          
+
   return 0;
 }