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

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


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

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).


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.21 => 1.22 ===
 **
 ** 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)
@@ -221,7 +229,7 @@
 
   if (self->len == self->size) {
       if (self->size) {
-          d = BTree_Realloc(self->data, sizeof(BTreeItem)*self->size*2);
+          d = BTree_Realloc(self->data, sizeof(BTreeItem) * self->size * 2);
 	  if (d == NULL)
 	      return -1;
           self->data = d;
@@ -236,8 +244,8 @@
       }
   }
 
-  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((PyObject *)v->ob_type, NULL);
@@ -285,6 +293,11 @@
 	  return BTree_clone(self);
   }
   else {
+      /* The BTree is empty.  Create an empty bucket.  See CAUTION in
+       * the comments preceding.
+       */
+      assert(index == 0);
+      d = self->data;
       d->child = BTree_newBucket(self);
       if (d->child == NULL)
 	  return -1;