[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