Commit aa887d42 authored by Tim Peters's avatar Tim Peters

_BTree_set(): Vastly reducing gratuitous differences between the trunk

and Zope3 branch versions of this function.  No semantic change.
parent 1c26a9ac
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
****************************************************************************/ ****************************************************************************/
#define BTREETEMPLATE_C "$Id: BTreeTemplate.c,v 1.38 2002/06/10 19:53:47 tim_one Exp $\n" #define BTREETEMPLATE_C "$Id: BTreeTemplate.c,v 1.39 2002/06/10 20:38:06 tim_one Exp $\n"
/* /*
** _BTree_get ** _BTree_get
...@@ -338,156 +338,142 @@ static int ...@@ -338,156 +338,142 @@ static int
_BTree_set(BTree *self, PyObject *keyarg, PyObject *value, _BTree_set(BTree *self, PyObject *keyarg, PyObject *value,
int unique, int noval) int unique, int noval)
{ {
int min, grew, copied=1, changed=0, bchanged=0; int min, grew, copied=1, changed=0, bchanged=0;
BTreeItem *d; BTreeItem *d;
KEY_TYPE key; KEY_TYPE key;
COPY_KEY_FROM_ARG(key, keyarg, copied); COPY_KEY_FROM_ARG(key, keyarg, copied);
UNLESS (copied) return -1; UNLESS (copied) return -1;
PER_USE_OR_RETURN(self, -1); PER_USE_OR_RETURN(self, -1);
UNLESS (self->len) if (!self->len) {
{ if (value) {
if (value) if (BTree_grow(self, 0, noval) < 0)
{ return -1;
if (BTree_grow(self, 0, noval) < 0) return -1; }
} else {
else PyErr_SetObject(PyExc_KeyError, keyarg);
{ return -1;
PyErr_SetObject(PyExc_KeyError, keyarg); }
return -1;
}
} }
BTREE_SEARCH(min, self, key, goto err); BTREE_SEARCH(min, self, key, goto err);
d = self->data + min; d = self->data + min;
if (SameType_Check(self, d->child)) if (SameType_Check(self, d->child))
grew= _BTree_set( BTREE(d->child), keyarg, value, unique, noval); grew = _BTree_set((BTree *)d->child, keyarg, value, unique, noval);
else else
grew=_bucket_set(BUCKET(d->child), keyarg, value, unique, noval, grew = _bucket_set((Bucket *)d->child, keyarg, value, unique, noval,
&bchanged); &bchanged);
if (grew < 0) goto err; if (grew < 0)
goto err;
if (grew)
{ if (grew) {
bchanged=1; /* A bucket changed size */ bchanged = 1; /* A bucket changed size */
if (value) /* got bigger */ if (value) { /* got bigger */
{ if (SameType_Check(self, d->child)) {
if (SameType_Check(self, d->child)) if (BTREE(d->child)->len > MAX_BTREE_SIZE(d->child)) {
{ if (BTree_grow(self, min, noval) < 0)
if (BTREE(d->child)->len > MAX_BTREE_SIZE(d->child)) goto err;
{ changed = 1;
if (BTree_grow(self, min, noval) < 0) goto err;
changed=1;
} }
} }
else else {
{ if (BUCKET(d->child)->len > MAX_BUCKET_SIZE(d->child)) {
if (BUCKET(d->child)->len > MAX_BUCKET_SIZE(d->child)) if (BTree_grow(self, min, noval) < 0)
{ goto err;
if (BTree_grow(self, min, noval) < 0) goto err; changed = 1;
changed=1;
} }
} }
} }
else /* got smaller */ else { /* got smaller */
{ if (min && grew > 1) {
if (min && grew > 1) /* Somebody below us deleted their first bucket and */
{ /* Somebody below us deleted their first bucket and */ /* and an intermediate tree couldn't handle it. */
/* and an intermediate tree couldn't handle it. */ if (BTree_deleteNextBucket(BTREE(d[-1].child)) < 0)
if (BTree_deleteNextBucket(BTREE(d[-1].child)) < 0) goto err;
goto err; grew = 1; /* Reset flag, since we handled it */
grew=1; /* Reset flag, since we handled it */
} }
if (BUCKET(d->child)->len == 0) if (BUCKET(d->child)->len == 0) { /* Got empty */
{ /* Got empty */ if (!SameType_Check(self, d->child)) {
/* We are about to delete a bucket. */
if (! SameType_Check(self, d->child)) if (min) {
{ /* We are about to delete a bucket. */ /* If it's not our first bucket, we can tell the
if (min) previous bucket to adjust it's reference to
{ /*If it's not our first bucket, we can tell the it. */
previous bucket to adjust it's reference to if (Bucket_deleteNextBucket(BUCKET(d[-1].child)) < 0)
it. */ goto err;
if (Bucket_deleteNextBucket(BUCKET(d[-1].child)) < 0)
goto err;
} }
else else {
{ /* If it's the first bucket, we can't adjust the /* If it's the first bucket, we can't adjust the
reference to it ourselves, so we'll just reference to it ourselves, so we'll just
increment the grew flag to indicate to a increment the grew flag to indicate to a
parent node that it's last bucket should parent node that it's last bucket should
adjust its reference. If there is no parent, adjust its reference. If there is no parent,
then there's nothing to do. */ then there's nothing to do. */
grew++; grew++;
} }
} }
self->len--; self->len--;
Py_DECREF(d->child); Py_DECREF(d->child);
if (min) if (min) {
{ DECREF_KEY(d->key);
DECREF_KEY(d->key);
} }
if (min < self->len) if (min < self->len)
memmove(d, d+1, (self->len-min)*sizeof(BTreeItem)); memmove(d, d+1, (self->len-min)*sizeof(BTreeItem));
if (! min) if (!min) {
{ if (self->len) {
if (self->len) /* We just deleted our first child, so we need to
{ /* We just deleted our first child, so we need to adjust our first bucket. */
adjust our first bucket. */ if (SameType_Check(self, self->data->child)) {
if (SameType_Check(self, self->data->child)) UNLESS (PER_USE(BTREE(self->data->child)))
{ goto err;
UNLESS (PER_USE(BTREE(self->data->child))) goto err; ASSIGNB(self->firstbucket,
ASSIGNB(self->firstbucket, BTREE(self->data->child)->firstbucket);
BTREE(self->data->child)->firstbucket); Py_XINCREF(self->firstbucket);
Py_XINCREF(self->firstbucket); PER_ALLOW_DEACTIVATION(BTREE(self->data->child));
PER_ALLOW_DEACTIVATION(BTREE(self->data->child)); PER_ACCESSED(BTREE(self->data->child));
PER_ACCESSED(BTREE(self->data->child));
} }
else else {
{ ASSIGNB(self->firstbucket,
ASSIGNB(self->firstbucket, BUCKET(self->data->child));
BUCKET(self->data->child)); Py_INCREF(self->firstbucket);
Py_INCREF(self->firstbucket);
} }
/* We can toss our first key now */ /* We can toss our first key now */
DECREF_KEY(self->data->key); DECREF_KEY(self->data->key);
} }
else else {
{ Py_XDECREF(self->firstbucket);
Py_XDECREF(self->firstbucket); self->firstbucket = 0;
self->firstbucket = 0;
} }
} }
changed=1;
changed=1;
} }
} }
} }
#ifdef PERSISTENT #ifdef PERSISTENT
if (changed if (changed
|| (bchanged /* The bucket changed */ || (bchanged /* The bucket changed */
&& self->len == 1 /* We have only one */ && self->len == 1 /* We have only one */
&& ! SameType_Check(self, self->data->child) /* It's our child */ && ! SameType_Check(self, self->data->child) /* It's our child */
&& BUCKET(self->data->child)->oid == NULL /* It's in our record */ && BUCKET(self->data->child)->oid == NULL /* It's in our record*/
) )
) )
if (PER_CHANGED(self) < 0) if (PER_CHANGED(self) < 0)
goto err; goto err;
#endif #endif
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return grew;
PER_ALLOW_DEACTIVATION(self); err:
PER_ACCESSED(self); PER_ALLOW_DEACTIVATION(self);
return grew; PER_ACCESSED(self);
return -1;
err:
PER_ALLOW_DEACTIVATION(self);
PER_ACCESSED(self);
return -1;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment