[Zodb-checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.1.2.23 BucketTemplate.c:1.1.2.22

Tim Peters tim.one@comcast.net
Fri, 7 Jun 2002 02:30:17 -0400


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

Modified Files:
      Tag: Zope-3x-branch
	BTreeTemplate.c BucketTemplate.c 
Log Message:
_BTree_clear() and _bucket_clear():  Exploit the KEY_TYPE_IS_PYOBJECT and
VALUE_TYPE_IS_PYOBJECT macros to generate zippier code.  Test for
self->data == NULL *before* dereferencing it in BTree nodes.  Rearrange
loops for speed.


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.1.2.22 => 1.1.2.23 ===
 _BTree_clear(BTree *self)
 {
-    int i, l;
+    const int len = self->len;
+
+    self->len = self->size = 0;
 
     /* The order in which we deallocate, from "top to bottom" is
        critical to prevent memory errors when the deallocation stack
        becomes huge when dealocating use linked lists of buckets.
+       XXX I don't understand that comment; there doesn't appear to be
+       XXX anything special in this code wrt deallocation order.  I
+       XXX suspect it might help to decref children in *reverse* order,
+       XXX to get the rightmost buckets cleared first.
     */
 
     if (self->firstbucket) {
@@ -527,18 +533,19 @@
 	self->firstbucket = NULL;
     }
 
-    for (l=self->len, i=0; i < l; i++) {
-	if (i) {
+    if (self->data) {
+        int i;
+        if (len > 0) /* 0 is special because key 0 is trash */
+            Py_DECREF(self->data[0].child);
+
+        for (i = 1; i < len; i++) {
+#ifdef KEY_TYPE_IS_PYOBJECT
 	    DECREF_KEY(self->data[i].key);
+#endif
+            Py_DECREF(self->data[i].child);
         }
-	Py_DECREF(self->data[i].child);
-    }
-    self->len = 0;
-
-    if (self->data) {
 	free(self->data);
-	self->data = 0;
-	self->size = 0;
+	self->data = NULL;
     }
 
     return 0;


=== Zope3/lib/python/Persistence/BTrees/BucketTemplate.c 1.1.2.21 => 1.1.2.22 ===
 _bucket_clear(Bucket *self)
 {
-  int i;
+    const int len = self->len;
+    /* Don't declare i at this level.  If neither keys nor values are
+     * PyObject*, i won't be referenced, and you'll get a nuisance compiler
+     * wng for declaring it here.
+     */
+    self->len = self->size = 0;
 
-  if (self->next) {
-      Py_DECREF(self->next);
-      self->next = NULL;
-  }
+    if (self->next) {
+        Py_DECREF(self->next);
+        self->next = NULL;
+    }
 
-  for (i = self->len; --i >= 0; ) {
-      DECREF_KEY(self->keys[i]);
-      if (self->values) {
-          DECREF_VALUE(self->values[i]);
-      }
-  }
-  self->len = 0;
-  if (self->values) {
-      free(self->values);
-      self->values = NULL;
-  }
-  if (self->keys) {
-      free(self->keys);
-      self->keys = NULL;
-  }
-  self->size = 0;
+    if (self->keys) {
+#ifdef KEY_TYPE_IS_PYOBJECT
+        int i;
+        for (i = 0; i < len; ++i)
+            DECREF_KEY(self->keys[i]);
+#endif
+        free(self->keys);
+        self->keys = NULL;
+    }
 
-  return 0;
+    if (self->values) {
+#ifdef VALUE_TYPE_IS_PYOBJECT
+        int i;
+        for (i = 0; i < len; ++i)
+            DECREF_VALUE(self->values[i]);
+#endif
+        free(self->values);
+        self->values = NULL;
+    }
+    return 0;
 }
 
 #ifdef PERSISTENT