[Zodb-checkins] CVS: StandaloneZODB/ZODB - DB.py:1.34 cPersistence.c:1.44 cPickleCache.c:1.34

Jeremy Hylton jeremy@zope.com
Tue, 6 Nov 2001 12:52:38 -0500


Update of /cvs-repository/StandaloneZODB/ZODB
In directory cvs.zope.org:/tmp/cvs-serv31470

Modified Files:
	DB.py cPersistence.c cPickleCache.c 
Log Message:
Merge a bunch of changes accidentally committed on the jeremy-Standby-branch.

DB.py: typo in comment
cPickleCache.c: fix cache sweep logic
cPersistence.c: small performance changes




=== StandaloneZODB/ZODB/DB.py 1.33 => 1.34 ===
             # Pool locks are tricky.  Basically, the lock needs to be
             # set whenever the pool becomes empty so that threads are
-            # forced to wait until the pool gets a connection it it.
+            # forced to wait until the pool gets a connection in it.
             # The lock is acquired when the (empty) pool is
             # created. The The lock is acquired just prior to removing
             # the last connection from the pool and just after adding


=== StandaloneZODB/ZODB/cPersistence.c 1.43 => 1.44 ===
 }
 
+static int
+checknoargs(PyObject *args)
+{
+  if (!PyTuple_Check(args))
+    return 0;
+  if (PyTuple_GET_SIZE(args) != 0) {
+    PyErr_Format(PyExc_TypeError, 
+		 "function takes exactly 0 arguments (%d given)",
+		 PyTuple_GET_SIZE(args));
+    return 0;
+  }
+  return 1;
+}
+
 static PyObject *
 callmethod(PyObject *self, PyObject *name)
 {
@@ -243,7 +257,8 @@
   if (idebug_log < 0) call_debug("reinit",self);
 #endif
 
-  if (args && ! PyArg_ParseTuple(args,"")) return NULL;
+  if (args && !checknoargs(args))
+    return NULL;
 
   if (self->state==cPersistent_UPTODATE_STATE && self->jar &&
       HasInstDict(self) && (dict=INSTANCE_DICT(self)))
@@ -273,7 +288,7 @@
 {
   PyObject *__dict__, *d=0;
 
-  UNLESS(PyArg_ParseTuple(args, "")) return NULL;
+  if (!checknoargs(args)) return NULL;
 
 #ifdef DEBUG_LOG
   if(idebug_log < 0) call_debug("get",self);
@@ -289,12 +304,12 @@
 	  
       for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); )
 	{
-	  if(PyString_Check(k) && (ck=PyString_AsString(k)) &&
+	  if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
 	     (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
 	    {
 	      UNLESS(d=PyDict_New()) goto err;
 	      for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); )
-		UNLESS(PyString_Check(k) && (ck=PyString_AsString(k)) &&
+		UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
 		       (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
 		  if(PyDict_SetItem(d,k,v) < 0) goto err;
 	      return d;
@@ -331,8 +346,8 @@
 	   
 	   if(PyDict_Check(v))
 	     {
-	       for(i=0; PyDict_Next(v,&i,&key,&e);)
-		 if(PyObject_SetItem(__dict__,key,e) < 0)
+	       for(i=0; PyDict_Next(v, &i, &key, &e);)
+		 if(PyDict_SetItem(__dict__, key, e) < 0)
 		   return NULL;
 	     }
 	   else
@@ -483,7 +498,7 @@
   PyObject *r;
 
   if (PyString_Check(name))
-    UNLESS(s=PyString_AsString(name)) return NULL;
+    UNLESS(s=PyString_AS_STRING(name)) return NULL;
 
   r = Per_getattr(self, name, s, PyExtensionClassCAPI->getattro);
   if (! r && self->state != cPersistent_GHOST_STATE &&
@@ -492,6 +507,7 @@
       )
     {
       PyErr_Clear();
+
       r=PyObject_GetAttr(OBJECT(self), py___getattr__);
       if (r) 
 	{
@@ -510,7 +526,7 @@
   char *name="";
 
   UNLESS(oname) return -1;
-  if(PyString_Check(oname)) UNLESS(name=PyString_AsString(oname)) return -1;
+  if(PyString_Check(oname)) UNLESS(name=PyString_AS_STRING(oname)) return -1;
 	
   if(*name=='_' && name[1]=='p' && name[2]=='_')
     {


=== StandaloneZODB/ZODB/cPickleCache.c 1.33 => 1.34 ===
 #define OBJECT(O) ((PyObject*)O)
 
+/* Compute the current time in the units and range used for peristent
+   objects. */
+#define PER_TIME() ((long)(time(NULL) / 3)) % 65536
+
 #define DONT_USE_CPERSISTENCECAPI
 #include "cPersistence.h"
 #include <time.h>
@@ -142,24 +146,27 @@
 static int 
 gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
 {
-
   if (v && key)
     {
       self->n++;
       if(v->ob_refcnt <= 1)
 	{
 	  self->sum_deal++;
+	  /* XXX The fact that this works will iterating over
+	     self->data with PyDict_Next() is an accident of the
+	     current Python dictionary implementation. */
 	  return PyDict_DelItem(self->data, key);
 	}
 
-      if (dt && 
+      if (dt >= 0 && 
 	  (! PyExtensionClass_Check(v)) &&
-	  ((cPersistentObject*)v)->jar==self->jar /* I'm paranoid */ &&
-	  ((cPersistentObject*)v)->state==cPersistent_UPTODATE_STATE
+	  ((cPersistentObject*)v)->jar == self->jar /* I'm paranoid */ &&
+	  ((cPersistentObject*)v)->state == cPersistent_UPTODATE_STATE
 	  )
 	{
 	  now -= ((cPersistentObject*)v)->atime;
-	  if (now < 0) now += 65536;
+	  if (now < 0) 
+	      now += 65536;
 	  self->na++;
 	  self->sum_age += now;
 	  if (now > dt)
@@ -169,7 +176,7 @@
 		 state.
 	      */
 	      self->sum_deac++;
-	      if (PyObject_SetAttr(v,py__p_changed,Py_None) < 0)
+	      if (PyObject_SetAttr(v, py__p_changed, Py_None) < 0)
 		PyErr_Clear();
 	    }
 	}
@@ -220,15 +227,18 @@
   int i;
   long now;
 
-  if (self->cache_size < 1) return 0;
-  if ((i=PyDict_Size(self->data)) < 1) return 0;
-
-  now=((long)(time(NULL)/3))%65536;
-  if (dt < 0) dt=0;
-  else dt /= 3;
+  if (self->cache_size < 1) 
+      return 0;
+  if ((i=PyDict_Size(self->data)) < 1) 
+      return 0;
+
+  now = PER_TIME();
+  if (dt > 0)
+      dt /= 3; 
 
   for(i=0; PyDict_Next(self->data, &i, &key, &v); )
-    if(gc_item(self,key,v,now,dt) < 0) return -1;
+    if (gc_item(self, key, v, now, dt) < 0) 
+	return -1;
   self->position=0;
 
   if(now-self->last_check > 1) update_stats(self, now);
@@ -243,24 +253,35 @@
   int i, l, last;
   time_t now;
 
-  if (self->cache_size < 1) return 0;
-  if((last=PyDict_Size(self->data)) < 0) return -1;
-
-  now=((long)(time(NULL)/3))%65536;
-  if (dt < 0) dt=0;
-  else dt /= 3;
+  if (self->cache_size < 1) 
+      return 0;
+  last = PyDict_Size(self->data);
+  if (last < 0)
+      return -1;
+
+  now = PER_TIME();
+  if (dt > 0)
+      dt /= 3;
 
   /* First time through should get refcounts to 1 */
   for(i=0; PyDict_Next(self->data, &i, &key, &v); )
-    if(gc_item(self,key,v,now,dt) < 0) return -1;
+      if (gc_item(self, key, v, now, dt) < 0) 
+	  return -1;
+
+  l = PyDict_Size(self->data);
 
-  if((l=PyDict_Size(self->data)) < 0) return -1;
-  while(l < last)
+  if (l < 0)
+      return -1;
+
+  while (l < last)
     {
-      for(i=0; PyDict_Next(self->data, &i, &key, &v); )
-	if(gc_item(self,key,v,now,dt) < 0) return -1;
-      last=l;
-      if((l=PyDict_Size(self->data)) < 0) return -1;
+      for (i=0; PyDict_Next(self->data, &i, &key, &v); )
+	  if (gc_item(self, key, v, now, dt) < 0) 
+	      return -1;
+      last = l;
+      l = PyDict_Size(self->data);
+      if (l < 0)
+	  return -1;
     }
 
   if(now-self->last_check > 1) update_stats(self, now);
@@ -280,7 +301,7 @@
   s=PyDict_Size(self->data);
   if (s < 1) return s;
 
-  now=((long)(time(NULL)/3))%65536;
+  now = PER_TIME();
 
   size=self->cache_size;
   self->cache_size=0;
@@ -322,9 +343,15 @@
 static PyObject *
 cc_full_sweep(ccobject *self, PyObject *args)
 {
-  int dt=0;
-  UNLESS(PyArg_ParseTuple(args, "|i", &dt)) return NULL;
-  UNLESS(-1 != fullgc(self,dt)) return NULL;
+  int dt = self->cache_age;
+  UNLESS(PyArg_ParseTuple(args, "|i:full_sweep", &dt)) return NULL;
+  if (dt < -1) 
+    {
+      PyErr_SetString(PyExc_ValueError, "age must be >= -1");
+      return NULL;
+    }
+  if (fullgc(self, dt) == -1)
+      return NULL;
   Py_INCREF(Py_None);
   return Py_None;
 }
@@ -332,9 +359,15 @@
 static PyObject *
 cc_reallyfull_sweep(ccobject *self, PyObject *args)
 {
-  int dt=0;
-  UNLESS(PyArg_ParseTuple(args, "|i", &dt)) return NULL;
-  UNLESS(-1 != reallyfullgc(self,dt)) return NULL;
+  int dt = self->cache_age;
+  UNLESS(PyArg_ParseTuple(args, "|i:minimize", &dt)) return NULL;
+  if (dt < -1) 
+    {
+      PyErr_SetString(PyExc_ValueError, "age must be >= -1");
+      return NULL;
+    }
+  if (reallyfullgc(self, dt) == -1)
+      return NULL;
   Py_INCREF(Py_None);
   return Py_None;
 }
@@ -344,7 +377,7 @@
 {
   int n=1;
 
-  UNLESS (PyArg_ParseTuple(args, "|i",&n)) return NULL;
+  UNLESS (PyArg_ParseTuple(args, "|i:incrgr",&n)) return NULL;
 
   for (; --n >= 0;)
     if(maybegc(self,NULL) < 0) return NULL;
@@ -369,15 +402,29 @@
 	  }
 	else
 	  {
-	    v=PyObject_CallFunction(self->setklassstate,
-				    "O", v);
+	    PyObject *t = PyTuple_New(1);
+	    if (t)
+	      {
+		PyTuple_SET_ITEM(t, 0, v);
+		v = PyObject_Call(self->setklassstate, t, NULL);
+		PyTuple_SET_ITEM(t, 0, NULL);
+		Py_DECREF(t);
+	      }
+	    else 
+	      {
+		v = t;
+	      }
 	    if (v) Py_DECREF(v);
 	    else PyErr_Clear();
 	  }
       else if (PyObject_DelAttr(v,py__p_changed) < 0)
 	PyErr_Clear();
     }
-  else PyErr_Clear();
+  else 
+    {
+      if (PyErr_Occurred())
+	PyErr_Clear();
+    }
 }
 
 static PyObject *
@@ -400,7 +447,7 @@
   }
   else {
     PyErr_Clear();
-    UNLESS (PyArg_ParseTuple(args, "O", &inv)) return NULL;
+    UNLESS (PyArg_ParseTuple(args, "O:invalidate", &inv)) return NULL;
     if (PyString_Check(inv))
       _invalidate(self, inv);
     else if (inv==Py_None)	/* All */
@@ -431,13 +478,14 @@
 {
   PyObject *r, *key, *d=0;
 
-  UNLESS (PyArg_ParseTuple(args,"O|O", &key, &d)) return NULL;
+  UNLESS (PyArg_ParseTuple(args, "O|O:get", &key, &d)) return NULL;
 
   UNLESS (r=PyDict_GetItem(self->data, key))
     {
       if (d) 
 	{
-	  PyErr_Clear();
+	  if (PyErr_Occurred())
+	    PyErr_Clear();
 	  r=d;
 	}
       else