[Zope-Checkins] CVS: Zope/lib/python/BTrees - BTreeTemplate.c:1.66

Tim Peters tim.one@comcast.net
Fri, 21 Jun 2002 01:43:57 -0400


Update of /cvs-repository/Zope/lib/python/BTrees
In directory cvs.zope.org:/tmp/cvs-serv12534

Modified Files:
	BTreeTemplate.c 
Log Message:
All internal consistency checks based on refcounts, in both old and new
code, are bogus when PERSISTENCE is #define'd.  Repair them.


=== Zope/lib/python/BTrees/BTreeTemplate.c 1.65 => 1.66 ===
     /* Non-empty BTree. */
     CHECK(self->firstbucket != NULL, "Non-empty BTree has NULL firstbucket");
+
+    /* Obscure:  The first bucket is pointed to at least by self->firstbucket
+     * and data[0].child of whichever BTree node it's a child of.  However,
+     * if persistence is enabled then the latter BTree node may be a ghost
+     * at this point, and so its pointers "don't count":  we can only rely
+     * on self's pointers being intact.
+     */
+#ifdef PERSISTENT
+    CHECK(self->firstbucket->ob_refcnt >= 1,
+          "Non-empty BTree firstbucket has refcount < 1");
+#else
     CHECK(self->firstbucket->ob_refcnt >= 2,
           "Non-empty BTree firstbucket has refcount < 2");
+#endif
+
     for (i = 0; i < self->len; ++i) {
         CHECK(self->data[i].child != NULL, "BTree has NULL child");
     }
+
     if (SameType_Check(self, self->data[0].child)) {
         /* Our children are also BTrees. */
         child = self->data[0].child;
@@ -93,7 +107,11 @@
                   "BTree children have different types");
             CHECK(child->len >= 1, "Bucket length < 1"); /* no empty buckets! */
             CHECK(child->len <= child->size, "Bucket len > size");
+#ifdef PERSISTENT
+            CHECK(child->ob_refcnt >= 1, "Bucket has refcount < 1");
+#else
             CHECK(child->ob_refcnt >= 2, "Bucket has refcount < 2");
+#endif
             if (i == self->len - 1)
                 bucketafter = nextbucket;
             else
@@ -505,8 +523,19 @@
     const int len = self->len;
 
     if (self->firstbucket) {
+        /* Obscure:  The first bucket is pointed to at least by
+         * self->firstbucket and data[0].child of whichever BTree node it's
+         * a child of.  However, if persistence is enabled then the latter
+         * BTree node may be a ghost at this point, and so its pointers "don't
+         * count":  we can only rely on self's pointers being intact.
+         */
+#ifdef PERSISTENT
+	ASSERT(self->firstbucket->ob_refcnt > 0,
+	       "Invalid firstbucket pointer", -1);
+#else
 	ASSERT(self->firstbucket->ob_refcnt > 1,
 	       "Invalid firstbucket pointer", -1);
+#endif
 	Py_DECREF(self->firstbucket);
 	self->firstbucket = NULL;
     }
@@ -967,7 +996,12 @@
 
     self->firstbucket = BUCKET(firstbucket);
     Py_INCREF(firstbucket);
-    assert(firstbucket->ob_refcnt > 1);
+#ifndef PERSISTENT
+    /* firstbucket is also the child of some BTree node, but that node may
+     * be a ghost if persistence is enabled.
+     */
+    assert(self->firstbucket->ob_refcnt > 1);
+#endif
 
     self->len = len;
 
@@ -1021,7 +1055,8 @@
 
   if (r) {
   	ASSIGN(r, Py_BuildValue("((O))", r));
-  } else {
+  }
+  else {
   	PyObject *error;
 	PyObject *value;
 	PyObject *traceback;