[Zope-Checkins] CVS: Zope/lib/python/BTrees - BTreeTemplate.c:1.71
Tim Peters
tim.one@comcast.net
Fri, 28 Jun 2002 16:52:31 -0400
Update of /cvs-repository/Zope/lib/python/BTrees
In directory cvs.zope.org:/tmp/cvs-serv4304
Modified Files:
BTreeTemplate.c
Log Message:
_BTree_set(): Localized the "if a BTree has only one bucket, persistence
may not believe the bucket is an object" pain. Simplified the exit maze.
=== Zope/lib/python/BTrees/BTreeTemplate.c 1.70 => 1.71 ===
{
int changed = 0; /* did I mutate? */
- int bchanged = 0; /* do I have a direct bucket child that mutated? */
int min; /* index of child I searched */
BTreeItem *d; /* self->data[min] */
int childlength; /* len(self->data[min].child) */
@@ -634,9 +633,24 @@
if (SameType_Check(self, d->child))
status = _BTree_set(BTREE(d->child), keyarg, value, unique, noval);
- else
+ else {
+ int bucket_changed = 0;
status = _bucket_set(BUCKET(d->child), keyarg,
- value, unique, noval, &bchanged);
+ value, unique, noval, &bucket_changed);
+#ifdef PERSISTENT
+ /* If a BTree contains only a single bucket, BTree.__getstate__()
+ * includes the bucket's entire state, and the bucket doesn't get
+ * an oid of its own. So if we have a single oid-less bucket that
+ * changed, it's *our* oid that should be marked as changed.
+ */
+ if (bucket_changed
+ && self->len == 1
+ && self->data[0].child->oid == NULL)
+ {
+ changed = 1;
+ }
+#endif
+ }
if (status == 0) goto Done;
if (status < 0) goto Error;
assert(status == 1 || status == 2);
@@ -647,8 +661,7 @@
*/
UNLESS(PER_USE(d->child)) goto Error;
childlength = d->child->len;
- PER_ALLOW_DEACTIVATION(d->child);
- PER_ACCESSED(d->child);
+ PER_UNUSE(d->child);
if (value) {
/* A bucket got bigger -- if it's "too big", split it. */
@@ -687,8 +700,7 @@
Bucket *nextbucket;
UNLESS(PER_USE(d->child)) goto Error;
nextbucket = BTREE(d->child)->firstbucket;
- PER_ALLOW_DEACTIVATION(d->child);
- PER_ACCESSED(d->child);
+ PER_UNUSE(d->child);
Py_XINCREF(nextbucket);
Py_DECREF(self->firstbucket);
@@ -731,8 +743,7 @@
/* 'changed' will be set true by the deletion code following. */
UNLESS(PER_USE(d->child)) goto Error;
nextbucket = BUCKET(d->child)->next;
- PER_ALLOW_DEACTIVATION(d->child);
- PER_ACCESSED(d->child);
+ PER_UNUSE(d->child);
Py_XINCREF(nextbucket);
Py_DECREF(self->firstbucket);
@@ -754,19 +765,11 @@
Done:
#ifdef PERSISTENT
- if (changed
- || (bchanged /* our kid was a bucket & it mutated */
- && self->len == 1 /* and we have only one child */
- && self->data[0].child->oid == NULL /* and it's in our record */
- )
- ) {
+ if (changed) {
if (PER_CHANGED(self) < 0) goto Error;
}
#endif
-
-_return:
- PER_ALLOW_DEACTIVATION(self);
- PER_ACCESSED(self);
+ PER_UNUSE(self);
return status;
Error:
@@ -776,8 +779,8 @@
*/
_BTree_clear(self);
}
- status = -1;
- goto _return;
+ PER_UNUSE(self);
+ return -1;
}
/*