[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeItemsTemplate.c:1.8
Tim Peters
tim.one@comcast.net
Sat, 22 Jun 2002 14:00:36 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv14495
Modified Files:
BTreeItemsTemplate.c
Log Message:
BTreeItems_item(), BTreeIter_next(): refactored to use a new
getBucketEntry() helper function. Getting all the error cases right is
too tedious to duplicate all this logic inline.
=== Zope3/lib/python/Persistence/BTrees/BTreeItemsTemplate.c 1.7 => 1.8 ===
}
+
+/* Return the right kind ('k','v','i') of entry from bucket b at offset i.
+ * b must be activated. Returns NULL on error.
+ */
+static PyObject *
+getBucketEntry(Bucket *b, int i, char kind)
+{
+ PyObject *result = NULL;
+
+ assert(b);
+ assert(0 <= i && i < b->len);
+
+ switch (kind) {
+
+ case 'k':
+ COPY_KEY_TO_OBJECT(result, b->keys[i]);
+ break;
+
+ case 'v':
+ COPY_VALUE_TO_OBJECT(result, b->values[i]);
+ break;
+
+ case 'i': {
+ PyObject *key;
+ PyObject *value;;
+
+ COPY_KEY_TO_OBJECT(key, b->keys[i]);
+ if (!key) break;
+
+ COPY_VALUE_TO_OBJECT(value, b->values[i]);
+ if (!value) {
+ Py_DECREF(key);
+ break;
+ }
+
+ result = PyTuple_New(2);
+ if (result) {
+ PyTuple_SET_ITEM(result, 0, key);
+ PyTuple_SET_ITEM(result, 1, value);
+ }
+ else {
+ Py_DECREF(key);
+ Py_DECREF(value);
+ }
+ break;
+ }
+
+ default:
+ PyErr_SetString(PyExc_AssertionError,
+ "getBucketEntry: unknown kind");
+ break;
+ }
+ return result;
+}
+
/*
** BTreeItems_item
**
@@ -235,44 +290,15 @@
static PyObject *
BTreeItems_item(BTreeItems *self, int i)
{
- PyObject *r, *k=0, *v=0;
-
- if (BTreeItems_seek(self, i) < 0) return NULL;
-
- PER_USE_OR_RETURN(self->currentbucket, NULL);
-
- switch(self->kind) {
-
- case 'v':
- COPY_VALUE_TO_OBJECT(r, self->currentbucket->values[self->currentoffset]);
- break;
-
- case 'i':
- COPY_KEY_TO_OBJECT(k, self->currentbucket->keys[self->currentoffset]);
- UNLESS (k) return NULL;
-
- COPY_VALUE_TO_OBJECT(v, self->currentbucket->values[self->currentoffset]);
- UNLESS (v) return NULL;
-
- UNLESS (r=PyTuple_New(2)) goto err;
+ PyObject *result;
- PyTuple_SET_ITEM(r, 0, k);
- PyTuple_SET_ITEM(r, 1, v);
- break;
+ if (BTreeItems_seek(self, i) < 0) return NULL;
- default:
- COPY_KEY_TO_OBJECT(r, self->currentbucket->keys[self->currentoffset]);
- break;
- }
-
- PER_UNUSE(self->currentbucket);
- return r;
-
- err:
- Py_DECREF(k);
- Py_XDECREF(v);
- PER_UNUSE(self->currentbucket);
- return NULL;
+ PER_USE_OR_RETURN(self->currentbucket, NULL);
+ result = getBucketEntry(self->currentbucket, self->currentoffset,
+ self->kind);
+ PER_UNUSE(self->currentbucket);
+ return result;
}
/*
@@ -607,34 +633,7 @@
}
/* Build the result object, from bucket at offset i. */
- switch (items->kind) {
-
- case 'k':
- COPY_KEY_TO_OBJECT(result, bucket->keys[i]);
- break;
-
- case 'v':
- COPY_VALUE_TO_OBJECT(result, bucket->values[i]);
- break;
-
- case 'i': {
- PyObject *key;
- PyObject *value;
-
- COPY_KEY_TO_OBJECT(key, bucket->keys[i]);
- COPY_VALUE_TO_OBJECT(value, bucket->values[i]);
-
- result = PyTuple_New(2);
- if (result == NULL) goto Done;
- PyTuple_SET_ITEM(result, 0, key);
- PyTuple_SET_ITEM(result, 1, value);
- break;
- }
-
- default:
- assert(!"unknown items->kind value");
- goto Done;
- }
+ result = getBucketEntry(bucket, i, items->kind);
/* Advance position for next call. */
if (bucket == items->lastbucket && i >= items->last) {