[Zope-Checkins] CVS: Zope/lib/python/BTrees - BTreeItemsTemplate.c:1.15 BTreeModuleTemplate.c:1.34

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


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

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().


=== Zope/lib/python/BTrees/BTreeItemsTemplate.c 1.14 => 1.15 ===
     }
     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.
          */
@@ -206,10 +207,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;


=== Zope/lib/python/BTrees/BTreeModuleTemplate.c 1.33 => 1.34 ===
 }
 
-/* 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;
-      PER_USE_OR_RETURN(first, NULL);
-      next = first->next;
-      PER_ALLOW_DEACTIVATION(first);
-      PER_ACCESSED(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 *