[Zodb-checkins] CVS: Zope/lib/python/BTrees - BTreeTemplate.c:1.47

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


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

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.


=== Zope/lib/python/BTrees/BTreeTemplate.c 1.46 => 1.47 ===
 }
 
+/* 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;
 
-  UNLESS (self->data && self->len)
-    {
-      IndexError(-1); /*XXX*/
-      return NULL;
+    UNLESS (self->data && self->len) {
+        IndexError(-1); /*XXX*/
+        return NULL;
     }
 
-  o = OBJECT(self->data[self->len - 1].child);
-  Py_INCREF(o);
-
-  UNLESS (SameType_Check(self, o)) return BUCKET(o);
-
-  self=BTREE(o);
-
-  PER_USE_OR_RETURN(self, NULL);
-  ASSIGN(o, OBJECT(BTree_lastBucket(self)));
-  PER_ALLOW_DEACTIVATION(self);
-  PER_ACCESSED(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