[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeItemsTemplate.c:1.4 BTreeModuleTemplate.c:1.6

Tim Peters tim.one@comcast.net
Mon, 17 Jun 2002 22:26:50 -0400


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

Modified Files:
	BTreeItemsTemplate.c BTreeModuleTemplate.c 
Log Message:
PreviousBucket():  Changed the signature.  Before, a NULL return could
mean any of no error, an expected index error, or an unexpected error;
naturally, callers conflated those.  The return value now distinguishes
among the cases.

BTreeItems_seek():  Use the new form of PreviousBucket().


=== Zope3/lib/python/Persistence/BTrees/BTreeItemsTemplate.c 1.3 => 1.4 ===
     }
     while (delta < 0) {         /* move left */
+        int status;
         /* Want to move left -delta positions; the most we can move left in
          * this bucket is currentoffset positions.
          */
@@ -207,10 +208,11 @@
         PER_ALLOW_DEACTIVATION(currentbucket);
         PER_ACCESSED(currentbucket);
         if (currentbucket == self->firstbucket) goto no_match;
-        b = PreviousBucket(currentbucket, self->firstbucket, i);
-        if (b == NULL) goto no_match; /* XXX this could be another error */
-        Py_DECREF(b);   /* we didn't really want it incref'ed to begin with */
-        currentbucket = b;
+        status = PreviousBucket(&currentbucket, self->firstbucket);
+        if (status == 0)
+            goto no_match;
+        else if (status < 0)
+            return -1;
         PER_USE_OR_RETURN(currentbucket, -1);
         pseudoindex -= currentoffset + 1;
         delta += currentoffset + 1;


=== Zope3/lib/python/Persistence/BTrees/BTreeModuleTemplate.c 1.5 => 1.6 ===
 }
 
-/* Returns a new reference to the bucket before current, in the bucket
- * chain starting at first.
- * Returns NULL on error.  IndexError(i) may or may not be set then (XXX I
- * don't know what the intent is, that's just what it does; should be redone).
+/* Search for the bucket immediately preceding *current, in the bucket chain
+ * starting at first.  current, *current and first must not be NULL.
+ *
+ * Return:
+ *     1    *current holds the correct bucket; this is a borrowed reference
+ *     0    no such bucket exists; *current unaltered
+ *    -1    error; *current unaltered
  */
-static Bucket *
-PreviousBucket(Bucket *current, Bucket *first, int i)
+static int
+PreviousBucket(Bucket **current, Bucket *first)
 {
-    if (!first)
-        return NULL;
-    if (first == current) {
-        IndexError(i);
-        return NULL;
-    }
+    Bucket *trailing = NULL;    /* first travels; trailing follows it */
+    int result = 0;
 
-    while (1) {
-        Bucket *next;
-	PyPersist_INCREF(first);
-	if (!PyPersist_IS_STICKY(first))
-	    return NULL;
-        next = first->next;
-        PER_ALLOW_DEACTIVATION(first);
-	PyPersist_SetATime(first);
+    assert(current && *current && first);
+    if (first == *current)
+        return 0;
 
-	if (next == current) {
-	    Py_INCREF(first);
-	    return first;
-        }
-        else if (next)
-	    first = next;
-        else {
-	    IndexError(i);
-	    return NULL;
-        }
-    }
+    do {
+        trailing = first;
+	PER_USE_OR_RETURN(first, -1);
+        first = first->next;
+        PER_ALLOW_DEACTIVATION(trailing);
+	PER_ACCESSED(trailing);
+
+	if (first == *current) {
+	    *current = trailing;
+	    result = 1;
+	    break;
+	}
+    } while (first);
+
+    return result;
 }
 
 static void *