[Zodb-checkins] CVS: Zope/lib/python/BTrees - BTreeTemplate.c:1.57

Tim Peters tim.one@comcast.net
Mon, 17 Jun 2002 14:49:50 -0400


Update of /cvs-repository/Zope/lib/python/BTrees
In directory cvs.zope.org:/tmp/cvs-serv27589

Modified Files:
	BTreeTemplate.c 
Log Message:
BTree_grow():  Documented more of what this does.  Noted that it leaves
a BTree in an invalid state when called with an empty BTree.  I still
need to change callers to ensure that the BTree is never left in that
invalid state (it can be now).


=== Zope/lib/python/BTrees/BTreeTemplate.c 1.56 => 1.57 ===
 **
 ** Arguments:	self	The BTree
-**		index	the index item to insert at
+**		index	self->data[index].child needs to be split.  index
+**                      must be 0 if self is empty (len == 0), and a new
+**                      empty bucket is created then.
+**              noval   Boolean; is this a set (true) or mapping (false)?
 **
 ** Returns:	 0	on success
 **		-1	on failure
+**
+** CAUTION:  If self is empty on entry, this routine adds an empty bucket.
+** That isn't a legitimate BTree; if the caller doesn't put something in
+** in the bucket (say, because of a later error), the BTree must be cleared
+** to get rid of the empty bucket.
 */
 static int
 BTree_grow(BTree *self, int index, int noval)
@@ -190,7 +198,7 @@
     {
       if (self->size)
         {
-          d = PyRealloc(self->data, sizeof(BTreeItem)*self->size*2);
+          d = PyRealloc(self->data, sizeof(BTreeItem) * self->size * 2);
           if (d == NULL)
             return -1;
           self->data = d;
@@ -198,7 +206,7 @@
         }
       else
         {
-          d = PyMalloc(sizeof(BTreeItem)*2);
+          d = PyMalloc(sizeof(BTreeItem) * 2);
           if (d == NULL)
             return -1;
           self->data = d;
@@ -206,9 +214,9 @@
         }
     }
 
-  d = self->data + index;
   if (self->len)
     {
+      d = self->data + index;
       v = d->child;
       /* Create a new object of the same type as the target value */
       e = SIZED(PyObject_CallObject(OBJECT(v->ob_type), NULL));
@@ -264,6 +272,11 @@
     }
   else
     {
+      /* The BTree is empty.  Create an empty bucket.  See CAUTION in
+       * the comments preceding.
+       */
+      assert(index == 0);
+      d = self->data;
       if (noval)
         {
           d->child = SIZED(PyObject_CallObject(OBJECT(&SetType), NULL));