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

Tim Peters tim.one@comcast.net
Wed, 12 Jun 2002 22:12:51 -0400


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

Modified Files:
	BTreeTemplate.c 
Log Message:
BTree_lastBucket():  documented what this returns (between who owns
references, what must not be and what may be a ghost, and exactly what
"last" means, it was surprisingly unclear).  Also simplified the
implementation (to my eyes -- it's arguable, but I'm the one working
on it, so my eyes count <wink>).  I believe this routine is key to
fixing the range-search bug efficiently.


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.10 => 1.11 ===
 }
 
+/* Return the rightmost bucket reachable from following child pointers
+ * from self.  The caller gets a new reference to this bucket.  Note that
+ * bucket 'next' pointers are not followed:  if self is an interior node
+ * of a BTree, this returns the rightmost bucket in that node's subtree.
+ * In case of error, returns NULL.
+ *
+ * self must not be a ghost; this isn't checked.  The result may be a ghost.
+ *
+ * Pragmatics:  Note that the rightmost bucket's last key is the largest
+ * key in self's subtree.
+ */
 static Bucket *
 BTree_lastBucket(BTree *self)
 {
-    PyObject *o;
+    Sized *pchild;
+    Bucket *result;
 
-    if (!(self->data && self->len)) {
-	IndexError(-1); /*XXX*/
-	return NULL;
+    UNLESS (self->data && self->len) {
+        IndexError(-1); /*XXX*/
+        return NULL;
     }
 
-    o = (PyObject *)self->data[self->len - 1].child;
-    Py_INCREF(o);
-
-    if (!SameType_Check(self, o))
-	return (Bucket *)o;
-
-    self = (BTree *)o;
-
-    PyPersist_INCREF(self);
-  if (!PyPersist_IS_STICKY(self))
-      return NULL;
-    ASSIGN(o, OBJECT(BTree_lastBucket(self)));
-    PyPersist_DECREF(self);
-    PyPersist_SetATime(self);
-
-    return (Bucket *)o;
+    pchild = self->data[self->len - 1].child;
+    if (SameType_Check(self, pchild)) {
+        self = BTREE(pchild);
+        PER_USE_OR_RETURN(self, NULL);
+        result = BTree_lastBucket(self);
+        PER_ALLOW_DEACTIVATION(self);
+        PER_ACCESSED(self);
+    }
+    else {
+        Py_INCREF(pchild);
+        result = BUCKET(pchild);
+    }
+    return result;
 }
 
 static int