Commit c88dc766 authored by Jeremy Hylton's avatar Jeremy Hylton

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
parent 20fc000a
......@@ -85,7 +85,7 @@
static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n"
"\n"
"$Id: cPersistence.c,v 1.43 2001/03/28 14:04:15 jim Exp $\n";
"$Id: cPersistence.c,v 1.44 2001/11/06 17:52:38 jeremy Exp $\n";
#include <string.h>
#include "cPersistence.h"
......@@ -137,6 +137,20 @@ init_strings(void)
return 0;
}
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 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
{
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
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 @@ Per__setstate__(cPersistentObject *self, PyObject *args)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
)
{
PyErr_Clear();
r=PyObject_GetAttr(OBJECT(self), py___getattr__);
if (r)
{
......@@ -510,7 +526,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
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]=='_')
{
......@@ -739,7 +755,7 @@ void
initcPersistence(void)
{
PyObject *m, *d, *s;
char *rev="$Revision: 1.43 $";
char *rev="$Revision: 1.44 $";
s = PyString_FromString("TimeStamp");
if (s == NULL)
......
......@@ -85,13 +85,17 @@
static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n"
"\n"
"$Id: cPickleCache.c,v 1.33 2001/03/28 14:36:30 jim Exp $\n";
"$Id: cPickleCache.c,v 1.34 2001/11/06 17:52:38 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#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 @@ staticforward PyTypeObject Cctype;
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 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
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 @@ fullgc(ccobject *self, int dt)
int i;
long now;
if (self->cache_size < 1) return 0;
if ((i=PyDict_Size(self->data)) < 1) return 0;
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;
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 @@ reallyfullgc(ccobject *self, int dt)
int i, l, last;
time_t now;
if (self->cache_size < 1) return 0;
if((last=PyDict_Size(self->data)) < 0) return -1;
if (self->cache_size < 1)
return 0;
last = PyDict_Size(self->data);
if (last < 0)
return -1;
now=((long)(time(NULL)/3))%65536;
if (dt < 0) dt=0;
else dt /= 3;
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ cc_full_sweep(ccobject *self, PyObject *args)
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 @@ cc_incrgc(ccobject *self, PyObject *args)
{
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 @@ _invalidate(ccobject *self, PyObject *key)
}
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 @@ cc_invalidate(ccobject *self, PyObject *args)
}
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 @@ cc_get(ccobject *self, PyObject *args)
{
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
......@@ -679,7 +727,7 @@ void
initcPickleCache(void)
{
PyObject *m, *d;
char *rev="$Revision: 1.33 $";
char *rev="$Revision: 1.34 $";
Cctype.ob_type=&PyType_Type;
......
......@@ -84,8 +84,8 @@
##############################################################################
"""Database objects
$Id: DB.py,v 1.33 2001/08/27 19:25:19 shane Exp $"""
__version__='$Revision: 1.33 $'[11:-2]
$Id: DB.py,v 1.34 2001/11/06 17:52:38 jeremy Exp $"""
__version__='$Revision: 1.34 $'[11:-2]
import cPickle, cStringIO, sys, POSException, UndoLogCompatible
from Connection import Connection
......@@ -442,7 +442,7 @@ class DB(UndoLogCompatible.UndoLogCompatible):
# 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
......
......@@ -85,7 +85,7 @@
static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n"
"\n"
"$Id: cPersistence.c,v 1.43 2001/03/28 14:04:15 jim Exp $\n";
"$Id: cPersistence.c,v 1.44 2001/11/06 17:52:38 jeremy Exp $\n";
#include <string.h>
#include "cPersistence.h"
......@@ -137,6 +137,20 @@ init_strings(void)
return 0;
}
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 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
{
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
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 @@ Per__setstate__(cPersistentObject *self, PyObject *args)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
)
{
PyErr_Clear();
r=PyObject_GetAttr(OBJECT(self), py___getattr__);
if (r)
{
......@@ -510,7 +526,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
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]=='_')
{
......@@ -739,7 +755,7 @@ void
initcPersistence(void)
{
PyObject *m, *d, *s;
char *rev="$Revision: 1.43 $";
char *rev="$Revision: 1.44 $";
s = PyString_FromString("TimeStamp");
if (s == NULL)
......
......@@ -85,13 +85,17 @@
static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n"
"\n"
"$Id: cPickleCache.c,v 1.33 2001/03/28 14:36:30 jim Exp $\n";
"$Id: cPickleCache.c,v 1.34 2001/11/06 17:52:38 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#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 @@ staticforward PyTypeObject Cctype;
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 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
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 @@ fullgc(ccobject *self, int dt)
int i;
long now;
if (self->cache_size < 1) return 0;
if ((i=PyDict_Size(self->data)) < 1) return 0;
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;
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 @@ reallyfullgc(ccobject *self, int dt)
int i, l, last;
time_t now;
if (self->cache_size < 1) return 0;
if((last=PyDict_Size(self->data)) < 0) return -1;
if (self->cache_size < 1)
return 0;
last = PyDict_Size(self->data);
if (last < 0)
return -1;
now=((long)(time(NULL)/3))%65536;
if (dt < 0) dt=0;
else dt /= 3;
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ cc_full_sweep(ccobject *self, PyObject *args)
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 @@ cc_incrgc(ccobject *self, PyObject *args)
{
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 @@ _invalidate(ccobject *self, PyObject *key)
}
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 @@ cc_invalidate(ccobject *self, PyObject *args)
}
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 @@ cc_get(ccobject *self, PyObject *args)
{
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
......@@ -679,7 +727,7 @@ void
initcPickleCache(void)
{
PyObject *m, *d;
char *rev="$Revision: 1.33 $";
char *rev="$Revision: 1.34 $";
Cctype.ob_type=&PyType_Type;
......
......@@ -85,7 +85,7 @@
static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n"
"\n"
"$Id: cPersistence.c,v 1.43 2001/03/28 14:04:15 jim Exp $\n";
"$Id: cPersistence.c,v 1.44 2001/11/06 17:52:38 jeremy Exp $\n";
#include <string.h>
#include "cPersistence.h"
......@@ -137,6 +137,20 @@ init_strings(void)
return 0;
}
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 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
{
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 @@ Per__getstate__(cPersistentObject *self, PyObject *args)
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 @@ Per__setstate__(cPersistentObject *self, PyObject *args)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
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 @@ Per_getattro(cPersistentObject *self, PyObject *name)
)
{
PyErr_Clear();
r=PyObject_GetAttr(OBJECT(self), py___getattr__);
if (r)
{
......@@ -510,7 +526,7 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
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]=='_')
{
......@@ -739,7 +755,7 @@ void
initcPersistence(void)
{
PyObject *m, *d, *s;
char *rev="$Revision: 1.43 $";
char *rev="$Revision: 1.44 $";
s = PyString_FromString("TimeStamp");
if (s == NULL)
......
......@@ -85,13 +85,17 @@
static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n"
"\n"
"$Id: cPickleCache.c,v 1.33 2001/03/28 14:36:30 jim Exp $\n";
"$Id: cPickleCache.c,v 1.34 2001/11/06 17:52:38 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
#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 @@ staticforward PyTypeObject Cctype;
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 @@ gc_item(ccobject *self, PyObject *key, PyObject *v, long now, int dt)
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 @@ fullgc(ccobject *self, int dt)
int i;
long now;
if (self->cache_size < 1) return 0;
if ((i=PyDict_Size(self->data)) < 1) return 0;
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;
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 @@ reallyfullgc(ccobject *self, int dt)
int i, l, last;
time_t now;
if (self->cache_size < 1) return 0;
if((last=PyDict_Size(self->data)) < 0) return -1;
if (self->cache_size < 1)
return 0;
last = PyDict_Size(self->data);
if (last < 0)
return -1;
now=((long)(time(NULL)/3))%65536;
if (dt < 0) dt=0;
else dt /= 3;
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ maybegc(ccobject *self, PyObject *thisv)
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 @@ cc_full_sweep(ccobject *self, PyObject *args)
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 @@ cc_incrgc(ccobject *self, PyObject *args)
{
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 @@ _invalidate(ccobject *self, PyObject *key)
}
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 @@ cc_invalidate(ccobject *self, PyObject *args)
}
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 @@ cc_get(ccobject *self, PyObject *args)
{
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
......@@ -679,7 +727,7 @@ void
initcPickleCache(void)
{
PyObject *m, *d;
char *rev="$Revision: 1.33 $";
char *rev="$Revision: 1.34 $";
Cctype.ob_type=&PyType_Type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment