[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.28

Jeremy Hylton jeremy@zope.com
Tue, 18 Jun 2002 19:12:43 -0400


Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv18867

Modified Files:
	BTreeTemplate.c 
Log Message:
Simplify _BTree_setstate() based on code review with Tim.

Bail immediately if the state is None, rather than adding a level of
indentation to all the code below.

The first thing the code does it call _BTree_clear(), so we're
guaranteed to be dealing with an empty BTree.  As a result, there's no
point to test the length of the BTree or call realloc on its data
pointers.  They're all 0.  This eliminates a few tests and a bit of
indentation at the end.

Inside the for loop, use an explicit temp variable rather than storing
into d->child and then checking whether d->child is a tuple.  (This is
handles the special case for a BTree with a single bucket.)


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.27 => 1.28 ===
 	return -1;
 
-    if (state != Py_None) {
-	if (!PyArg_ParseTuple(state,"O|O", &items, &firstbucket))
-	    return -1;
+    if (state == Py_None)
+	return 0;
 
-	len = PyTuple_Size(items);
-	if (len < 0)
-	    return -1;
-	len = (len + 1) / 2;
+    if (!PyArg_ParseTuple(state,"O|O:__setstate__", &items, &firstbucket))
+	return -1;
 
-	if (len > self->size) {
-	    UNLESS (d = BTree_Realloc(self->data, sizeof(BTreeItem)*len))
+    len = PyTuple_Size(items);
+    if (len < 0)
+	return -1;
+    len = (len + 1) / 2;
+    
+    assert(len > 0); /* If the BTree is empty, it's state is None. */
+    assert(self->size == 0); /* We called _BTree_clear(). */
+    
+    self->data = BTree_Malloc(sizeof(BTreeItem) * len);
+    if (self->data == NULL)
+	return -1;
+    self->size = len;
+
+    for (i = 0, d = self->data, l = 0; i < len; i++, d++) {
+	PyObject *v;
+	if (i) {
+	    COPY_KEY_FROM_ARG(d->key, PyTuple_GET_ITEM(items, l), copied);
+	    l++;
+	    if (!copied)
 		return -1;
-	    self->data=d;
-	    self->size=len;
-        }
-
-	for (i = 0, d = self->data, l = 0; i < len; i++, d++) {
-	    if (i) {
-		COPY_KEY_FROM_ARG(d->key, PyTuple_GET_ITEM(items,l), copied);
-		l++;
-		if (!copied)
-		    return -1;
-		INCREF_KEY(d->key);
-            }
-	    d->child = (Sized *)PyTuple_GET_ITEM(items, l);
-	    if (PyTuple_Check(d->child)) {
-		d->child = BTree_newBucket(self);
-		UNLESS (d->child)
+	    INCREF_KEY(d->key);
+	}
+	v = PyTuple_GET_ITEM(items, l);
+	if (PyTuple_Check(v)) {
+	    /* Handle the special case in __getstate__() for a BTree
+	       with a single bucket. */
+	    d->child = BTree_newBucket(self);
+	    if (!d->child)
+		return -1;
+	    if (noval) {
+		if (_set_setstate(BUCKET(d->child), v) < 0)
 		    return -1;
-		if (noval) {
-		    if (_set_setstate(BUCKET(d->child),
-				      PyTuple_GET_ITEM(items,l)) < 0)
-			return -1;
-                } else {
-		    if (_bucket_setstate(BUCKET(d->child),
-					 PyTuple_GET_ITEM(items,l)) < 0)
-			return -1;
-                }
 	    } else {
-		Py_INCREF(d->child);
-            }
-	    l++;
-        }
-
-	if (len)
-        {
-	    if (!firstbucket)
-		firstbucket = (PyObject *)self->data->child;
-
-	    /* XXX what is this? */
-	    if (!PyObject_IsInstance(firstbucket, (PyObject *)
-				     (noval ? &SetType : &BucketType)))
-            {
-		PyErr_SetString(PyExc_TypeError,
-				"No firstbucket in non-empty BTree");
-		return -1;
-            }
-
-	    self->firstbucket = BUCKET(firstbucket);
-	    Py_INCREF(firstbucket);
-        }
-
-	self->len=len;
+		if (_bucket_setstate(BUCKET(d->child), v) < 0)
+		    return -1;
+	    }
+	} else {
+	    d->child = (Sized *)v;
+	    Py_INCREF(v);
+	}
+	l++;
+    }
+    
+    if (!firstbucket)
+	firstbucket = (PyObject *)self->data->child;
+	
+    if (!PyObject_IsInstance(firstbucket, (PyObject *)
+			     (noval ? &SetType : &BucketType))) {
+	PyErr_SetString(PyExc_TypeError,
+			"No firstbucket in non-empty BTree");
+	return -1;
     }
+    self->firstbucket = BUCKET(firstbucket);
+    Py_INCREF(firstbucket);
+    assert(self->firstbucket->ob_refcnt > 1);
+
+    self->len = len;
 
     return 0;
 }