[Zodb-checkins] CVS: StandaloneZODB/ZODB - cPickleCache.c:1.33.68.1

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


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

Modified Files:
      Tag: jeremy-Standby-branch
	cPickleCache.c 
Log Message:
Fix handling of age argument to full_sweep() and minimize().

The cache routines that attempt to remove objects take an optional age
argument.  The documentation and the implementation have been out of
sync for a while.  This checkin gets them back on the same page.

The cache routines remove objects from the cache when they have not
been accessed in age seconds.  If no age is specified the default
cache age is used.  If the age is -1, objects are only removed if they
are not referenced.

The implementation used to default to 0 and treat any of 0 through 2
the way -1 is now handled.  This was all accidental.

Also, add a range change in minimize() and full_sweep() so that values
less than -1 raised ValueError.  (What would it mean to sweep in the
future?)



=== StandaloneZODB/ZODB/cPickleCache.c 1.33 => 1.33.68.1 ===
 #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,7 +146,6 @@
 static int 
 gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
 {
-
   if (v && key)
     {
       self->n++;
@@ -152,14 +155,15 @@
 	  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 +173,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 +224,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 +250,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 +298,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 +340,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 +356,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 +374,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;
@@ -400,7 +430,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 */
@@ -437,7 +467,9 @@
     {
       if (d) 
 	{
-	  PyErr_Clear();
+	  PyErr_Clear(); /* Note that PyDict_GetItem() doesn't set an
+			    exception, but a comparison within it
+			    might. */
 	  r=d;
 	}
       else