[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;