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

Tim Peters tim.one@comcast.net
Fri, 21 Jun 2002 14:06:55 -0400


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

Modified Files:
	BTreeTemplate.c 
Log Message:
_BTree_get():  For a little speed boost in a frequent operation, removed
the recursion (iteration is quite natural here -- it was tail-recursive).


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.33 => 1.34 ===
 _BTree_get(BTree *self, PyObject *keyarg, int has_key)
 {
-  KEY_TYPE key;
-  int min;              /* index of child to search */
-  PyObject *r = NULL;   /* result object */
-  int copied = 1;
+    KEY_TYPE key;
+    PyObject *result = NULL;    /* guilty until proved innocent */
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS (copied) return NULL;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS (copied) return NULL;
 
-  PyPersist_INCREF(self);
-  if (!PyPersist_IS_STICKY(self))
-      return NULL;
-
-  BTREE_SEARCH(min, self, key, goto Error);
-  if (self->len)
-    {
-      if (SameType_Check(self, self->data[min].child))
-        r=_BTree_get( BTREE(self->data[min].child), keyarg,
-                      has_key ? has_key + 1: 0);
-      else
-        r=_bucket_get(BUCKET(self->data[min].child), keyarg,
-                      has_key ? has_key + 1: 0);
+    PER_USE_OR_RETURN(self, NULL);
+    if (self->len == 0) {
+        /* empty BTree */
+        if (has_key)
+            result = PyInt_FromLong(0);
+        else
+            PyErr_SetObject(PyExc_KeyError, keyarg);
     }
-  else
-    {  /* No data */
-      UNLESS (has_key)
-        {
-          PyErr_SetObject(PyExc_KeyError, keyarg);
-          r=NULL;
+    else {
+        for (;;) {
+            int i;
+            Sized *child;
+
+            BTREE_SEARCH(i, self, key, goto Done);
+            child = self->data[i].child;
+            has_key += has_key != 0;    /* bump depth counter, maybe */
+            if (SameType_Check(self, child)) {
+                PER_UNUSE(self);
+                self = BTREE(child);
+                PER_USE_OR_RETURN(self, NULL);
+            }
+            else {
+                result = _bucket_get(BUCKET(child), keyarg, has_key);
+                break;
+            }
         }
-      else
-        r=PyInt_FromLong(0);
     }
 
-Error:
-  PyPersist_DECREF(self);
-  PyPersist_SetATime(self);
-  return r;
+Done:
+    PER_UNUSE(self);
+    return result;
 }
 
 static PyObject *