[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.40
Tim Peters
tim.one@comcast.net
Fri, 28 Jun 2002 16:52:52 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv4832
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.
=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.39 => 1.40 ===
{
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) */
@@ -618,8 +617,7 @@
COPY_KEY_FROM_ARG(key, keyarg, copied);
if (!copied) return -1;
- PyPersist_INCREF(self);
- if (!PyPersist_IS_STICKY(self)) return -1;
+ PER_USE_OR_RETURN(self, -1);
self_was_empty = self->len == 0;
if (self_was_empty) {
@@ -641,9 +639,25 @@
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 -- the
+ * bucket doesn't have one.
+ */
+ if (bucket_changed
+ && self->len == 1
+ && self->data[0].child->po_oid == NULL)
+ {
+ changed = 1;
+ }
+#endif
+ }
if (status == 0) goto Done;
if (status < 0) goto Error;
assert(status == 1 || status == 2);
@@ -654,8 +668,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. */
@@ -694,8 +707,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);
@@ -738,8 +750,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);
@@ -761,19 +772,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->po_oid == NULL /* and it's in our record */
- )
- ) {
+ if (changed) {
if (PyPersist_CHANGED(self) < 0) goto Error;
}
#endif
-
-_return:
- PyPersist_DECREF(self);
- PyPersist_SetATime(self);
+ PER_UNUSE(self);
return status;
Error:
@@ -783,8 +786,8 @@
*/
_BTree_clear(self);
}
- status = -1;
- goto _return;
+ PER_UNUSE(self);
+ return -1;
}
/*