Commit 8007802d authored by Jeremy Hylton's avatar Jeremy Hylton

Remove the cache_deactivate_after argument from the cPickleCache

constructor, since it is ignored and there is no current plan to
support two caches with almost-but-not-quite-the-same arguments.

This change has effects in many files.  The Connection and DB don't
pass this argument and don't bother setting it explicitly when it is
reset via DB APIs like setCacheDeactivateAfter().  XXX These APIs
remain, since existing code may depend on them, but they have no
effect.

New policy in cPersistence.c: A Persistent object can't have its
_p_jar set or deleted once it is in a cache.  Persistent already
implemented this policy for _p_oid; it seems safer to do the same for
the jar.

Add ringlen() method to cache objects (implemented as cc_ringlen).
This returns the length of the doubly linked list of non-ghost
objects.  Same as len(cache.lru_items()), but more efficient.  Only
used for testing at the moment.

In ring_corrupt(), don't raise a new exception if one has already been
set.  The old behavior masked useful information about the original
error / traceback.
parent bc0d92c9
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.58 2002/04/05 01:12:48 jeremy Exp $\n"; "$Id: cPersistence.c,v 1.59 2002/04/15 18:42:51 jeremy Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
return -1; return -1;
if (*name == '_' && name[1] == 'p' && name[2] == '_') { if (*name == '_' && name[1] == 'p' && name[2] == '_') {
if (name[3] == 'o' && name[4] == 'i' && name[5] == 'd' && ! name[6]) { if (strcmp(name + 3, "oid") == 0) {
if (self->cache) { if (self->cache) {
int result; int result;
if (v == NULL) { if (v == NULL) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not delete the oid of a cached object"); "can not delete oid of cached object");
return -1; return -1;
} }
if (PyObject_Cmp(self->oid, v, &result) < 0) if (PyObject_Cmp(self->oid, v, &result) < 0)
return -1; return -1;
if (result) { if (result) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not change the oid of a cached object"); "can not change oid of cached object");
return -1; return -1;
} }
} }
...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
ASSIGN(self->oid, v); ASSIGN(self->oid, v);
return 0; return 0;
} }
if (name[3]=='j' && name[4]=='a' && name[5]=='r' && ! name[6]) else if (strcmp(name + 3, "jar") == 0) {
{ if (self->cache && self->jar) {
int result;
if (v == NULL) {
PyErr_SetString(PyExc_ValueError,
"can not delete jar of cached object");
return -1;
}
if (PyObject_Cmp(self->jar, v, &result) < 0)
return -1;
if (result) {
PyErr_SetString(PyExc_ValueError,
"can not change jar of cached object");
return -1;
}
}
Py_XINCREF(v); Py_XINCREF(v);
ASSIGN(self->jar, v); ASSIGN(self->jar, v);
return 0; return 0;
} }
if (name[3]=='s' && strcmp(name+4,"erial")==0) else if (strcmp(name + 3, "serial") == 0) {
{ if (v) {
if (v) if (PyString_Check(v) && PyString_GET_SIZE(v) == 8)
{ memcpy(self->serial, PyString_AS_STRING(v), 8);
if (PyString_Check(v) && PyString_Size(v)==8) else {
memcpy(self->serial, PyString_AS_STRING(v), 8);
else
{
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"_p_serial must be an 8-character string"); "_p_serial must be an 8-character string");
return -1; return -1;
} }
} } else
else memset(self->serial, 0, 8);
memset(self->serial, 0, 8);
return 0; return 0;
} }
if (name[3]=='c' && strcmp(name+4,"hanged")==0) else if (strcmp(name+3, "changed") == 0) {
{ if (!v)
if (! v)
{ {
/* delatter is used to invalidate the object /* delatter is used to invalidate the object
*even* if it has changed. *even* if it has changed.
......
...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them. ...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them.
static char cPickleCache_doc_string[] = static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n" "Defines the PickleCache used by ZODB Connection objects.\n"
"\n" "\n"
"$Id: cPickleCache.c,v 1.57 2002/04/15 15:17:33 chrisw Exp $\n"; "$Id: cPickleCache.c,v 1.58 2002/04/15 18:42:51 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;} #define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E)) #define UNLESS(E) if(!(E))
...@@ -150,7 +150,9 @@ typedef struct { ...@@ -150,7 +150,9 @@ typedef struct {
} ccobject; } ccobject;
#ifdef MUCH_RING_CHECKING
static int present_in_ring(ccobject *self, CPersistentRing *target); static int present_in_ring(ccobject *self, CPersistentRing *target);
#endif
static int ring_corrupt(ccobject *self, const char *context); static int ring_corrupt(ccobject *self, const char *context);
static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v); static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v);
...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context) ...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context)
static int static int
scan_gc_items(ccobject *self,int target) scan_gc_items(ccobject *self,int target)
{ {
/* This function must only be called with the ring lock held */ /* This function must only be called with the ring lock held,
because it places a non-object placeholder in the ring.
*/
cPersistentObject *object; cPersistentObject *object;
int error; int error;
...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid) ...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid)
return 0; return 0;
} }
static PyObject *
cc_ringlen(ccobject *self, PyObject *args)
{
CPersistentRing *here;
int c = 0;
if (!PyArg_ParseTuple(args, ":ringlen"))
return NULL;
for (here = self->ring_home.next; here != &self->ring_home;
here = here->next)
c++;
return PyInt_FromLong(c);
}
static struct PyMethodDef cc_methods[] = { static struct PyMethodDef cc_methods[] = {
{"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS, {"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS,
...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = { ...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = {
"invalidate(oids) -- invalidate one, many, or all ids"}, "invalidate(oids) -- invalidate one, many, or all ids"},
{"get", (PyCFunction)cc_get, METH_VARARGS, {"get", (PyCFunction)cc_get, METH_VARARGS,
"get(key [, default]) -- get an item, or a default"}, "get(key [, default]) -- get an item, or a default"},
{"ringlen", (PyCFunction)cc_ringlen, METH_VARARGS,
"ringlen() -- Returns number of non-ghost items in cache."},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
cPersistentObject *p; cPersistentObject *p;
if (!PyExtensionInstance_Check(v)) { if (!PyExtensionInstance_Check(v)) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
return -1; return -1;
} }
class = (PyExtensionClass *)(v->ob_type); class = (PyExtensionClass *)(v->ob_type);
if (!((class->class_flags & PERSISTENT_TYPE_FLAG) if (!((class->class_flags & PERSISTENT_TYPE_FLAG)
&& v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) { && v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
/* Must be either persistent classes (ie ZClasses), or instances /* Must be either persistent classes (ie ZClasses), or instances
of persistent classes (ie Python classeses that derive from of persistent classes (ie Python classeses that derive from
...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
* persistent class. * persistent class.
*/ */
oid = PyObject_GetAttr(v, py__p_oid); oid = PyObject_GetAttr(v, py__p_oid);
if (oid == NULL) if (oid == NULL)
return -1; return -1;
/* XXX key and oid should both be PyString objects. /* XXX key and oid should both be PyString objects.
...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
return -1; return -1;
} }
/* XXX check that object has valid _p_jar? */
object_again = object_from_oid(self, key); object_again = object_from_oid(self, key);
if (object_again) { if (object_again) {
if (object_again != v) { if (object_again != v) {
...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key) ...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key)
if (PyDict_DelItem(self->data, key) < 0) { if (PyDict_DelItem(self->data, key) < 0) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"unexpectedly couldnt remove key in cc_ass_sub"); "unexpectedly couldn't remove key in cc_ass_sub");
return -1; return -1;
} }
...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context) ...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context)
if (here->next->prev != here) if (here->next->prev != here)
return 10; return 10;
if (!self->ring_lock) { if (!self->ring_lock) {
/* if the ring must be locked then it only contains object other than persistent instances */ /* If the ring must be locked, then it only contains
object other than persistent instances.
*/
if (here != &self->ring_home) { if (here != &self->ring_home) {
cPersistentObject *object = object_from_ring(self, here, cPersistentObject *object = object_from_ring(self, here,
context); context);
...@@ -986,17 +1008,19 @@ static int ...@@ -986,17 +1008,19 @@ static int
ring_corrupt(ccobject *self, const char *context) ring_corrupt(ccobject *self, const char *context)
{ {
#ifdef MUCH_RING_CHECKING #ifdef MUCH_RING_CHECKING
int code = _ring_corrupt(self,context); int code = _ring_corrupt(self, context);
if (code) { if (code) {
PyErr_Format(PyExc_RuntimeError, if (!PyErr_Occurred())
"broken ring (code %d) in %s, size %d", PyErr_Format(PyExc_RuntimeError,
code, context, PyDict_Size(self->data)); "broken ring (code %d) in %s, size %d",
code, context, PyDict_Size(self->data));
return code; return code;
} }
#endif #endif
return 0; return 0;
} }
#ifdef MUCH_RING_CHECKING
static int static int
present_in_ring(ccobject *self,CPersistentRing *target) present_in_ring(ccobject *self,CPersistentRing *target)
{ {
...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target) ...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target)
here = here->next; here = here->next;
} }
} }
#endif
static PyMappingMethods cc_as_mapping = { static PyMappingMethods cc_as_mapping = {
(inquiry)cc_length, /*mp_length*/ (inquiry)cc_length, /*mp_length*/
...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = { ...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = {
}; };
static ccobject * static ccobject *
newccobject(PyObject *jar, int cache_size, int cache_age) newccobject(PyObject *jar, int cache_size)
{ {
ccobject *self; ccobject *self;
...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age) ...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age)
static PyObject * static PyObject *
cCM_new(PyObject *self, PyObject *args) cCM_new(PyObject *self, PyObject *args)
{ {
int cache_size=100, cache_age=1000; int cache_size=100;
PyObject *jar; PyObject *jar;
if (!PyArg_ParseTuple(args, "O|ii", &jar, &cache_size, &cache_age)) if (!PyArg_ParseTuple(args, "O|i", &jar, &cache_size))
return NULL; return NULL;
return (PyObject*)newccobject(jar, cache_size, cache_age); return (PyObject*)newccobject(jar, cache_size);
} }
static struct PyMethodDef cCM_methods[] = { static struct PyMethodDef cCM_methods[] = {
{"PickleCache",(PyCFunction)cCM_new, METH_VARARGS, ""}, {"PickleCache", (PyCFunction)cCM_new, METH_VARARGS, ""},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
############################################################################## ##############################################################################
"""Database connection support """Database connection support
$Id: Connection.py,v 1.65 2002/04/13 20:17:22 jeremy Exp $""" $Id: Connection.py,v 1.66 2002/04/15 18:42:50 jeremy Exp $"""
__version__='$Revision: 1.65 $'[11:-2] __version__='$Revision: 1.66 $'[11:-2]
from cPickleCache import PickleCache, MUCH_RING_CHECKING from cPickleCache import PickleCache, MUCH_RING_CHECKING
from POSException import ConflictError, ReadConflictError from POSException import ConflictError, ReadConflictError
...@@ -69,11 +69,14 @@ class Connection(ExportImport.ExportImport): ...@@ -69,11 +69,14 @@ class Connection(ExportImport.ExportImport):
cache_deactivate_after=60): cache_deactivate_after=60):
"""Create a new Connection""" """Create a new Connection"""
self._version=version self._version=version
self._cache=cache=PickleCache(self, cache_size, cache_deactivate_after) self._cache = cache = PickleCache(self, cache_size)
if version: if version:
# Caches for versions end up empty if the version # Caches for versions end up empty if the version
# is not used for a while. Non-version caches # is not used for a while. Non-version caches
# keep their content indefinitely. # keep their content indefinitely.
# XXX Why do we want version caches to behave this way?
self._cache.cache_drain_resistance = 100 self._cache.cache_drain_resistance = 100
self._incrgc=self.cacheGC=cache.incrgc self._incrgc=self.cacheGC=cache.incrgc
self._invalidated=d={} self._invalidated=d={}
...@@ -209,8 +212,7 @@ class Connection(ExportImport.ExportImport): ...@@ -209,8 +212,7 @@ class Connection(ExportImport.ExportImport):
self._code_timestamp = global_code_timestamp self._code_timestamp = global_code_timestamp
self._invalidated.clear() self._invalidated.clear()
orig_cache = self._cache orig_cache = self._cache
self._cache = PickleCache(self, orig_cache.cache_size, self._cache = PickleCache(self, orig_cache.cache_size)
orig_cache.cache_age)
def abort(self, object, transaction): def abort(self, object, transaction):
"""Abort the object in the transaction. """Abort the object in the transaction.
...@@ -226,7 +228,8 @@ class Connection(ExportImport.ExportImport): ...@@ -226,7 +228,8 @@ class Connection(ExportImport.ExportImport):
self._cache.full_sweep(dt) self._cache.full_sweep(dt)
def cacheMinimize(self, dt=0): def cacheMinimize(self, dt=0):
self._cache.minimize(dt) # dt is ignored
self._cache.minimize()
__onCloseCallbacks = None __onCloseCallbacks = None
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
############################################################################## ##############################################################################
"""Database objects """Database objects
$Id: DB.py,v 1.40 2002/03/27 10:14:04 htrd Exp $""" $Id: DB.py,v 1.41 2002/04/15 18:42:51 jeremy Exp $"""
__version__='$Revision: 1.40 $'[11:-2] __version__='$Revision: 1.41 $'[11:-2]
import cPickle, cStringIO, sys, POSException, UndoLogCompatible import cPickle, cStringIO, sys, POSException, UndoLogCompatible
from Connection import Connection from Connection import Connection
...@@ -62,10 +62,10 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -62,10 +62,10 @@ class DB(UndoLogCompatible.UndoLogCompatible):
self._temps=[] self._temps=[]
self._pool_size=pool_size self._pool_size=pool_size
self._cache_size=cache_size self._cache_size=cache_size
self._cache_deactivate_after=cache_deactivate_after self._cache_deactivate_after = cache_deactivate_after
self._version_pool_size=version_pool_size self._version_pool_size=version_pool_size
self._version_cache_size=version_cache_size self._version_cache_size=version_cache_size
self._version_cache_deactivate_after=version_cache_deactivate_after self._version_cache_deactivate_after = version_cache_deactivate_after
self._miv_cache={} self._miv_cache={}
...@@ -157,17 +157,19 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -157,17 +157,19 @@ class DB(UndoLogCompatible.UndoLogCompatible):
Organized by class.""" Organized by class."""
detail={} detail = {}
def f(con,detail=detail,have_detail=detail.has_key): def f(con, detail=detail, have_detail=detail.has_key):
for oid, ob in con._cache.items(): for oid, ob in con._cache.items():
module = getattr(ob.__class__, '__module__', '') module = getattr(ob.__class__, '__module__', '')
module = module and '%s.' % module or '' module = module and '%s.' % module or ''
c="%s%s" % (module, ob.__class__.__name__) c = "%s%s" % (module, ob.__class__.__name__)
if have_detail(c): detail[c]=detail[c]+1 if have_detail(c):
else: detail[c]=1 detail[c] = detail[c] + 1
else:
detail[c] = 1
self._connectionMap(f) self._connectionMap(f)
detail=detail.items() detail = detail.items()
detail.sort() detail.sort()
return detail return detail
...@@ -224,7 +226,7 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -224,7 +226,7 @@ class DB(UndoLogCompatible.UndoLogCompatible):
def cacheSize(self): def cacheSize(self):
m=[0] m=[0]
def f(con, m=m): def f(con, m=m):
m[0]=m[0]+con._cache.cache_non_ghost_count m[0] = m[0] + con._cache.cache_non_ghost_count
self._connectionMap(f) self._connectionMap(f)
return m[0] return m[0]
...@@ -247,8 +249,11 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -247,8 +249,11 @@ class DB(UndoLogCompatible.UndoLogCompatible):
def exportFile(self, oid, file=None): def exportFile(self, oid, file=None):
raise 'Not yet implemented' raise 'Not yet implemented'
def getCacheDeactivateAfter(self): return self._cache_deactivate_after def getCacheDeactivateAfter(self):
def getCacheSize(self): return self._cache_size return self._cache_deactivate_after
def getCacheSize(self):
return self._cache_size
def getName(self): return self._storage.getName() def getName(self): return self._storage.getName()
...@@ -258,9 +263,12 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -258,9 +263,12 @@ class DB(UndoLogCompatible.UndoLogCompatible):
def getVersionCacheDeactivateAfter(self): def getVersionCacheDeactivateAfter(self):
return self._version_cache_deactivate_after return self._version_cache_deactivate_after
def getVersionCacheSize(self): return self._version_cache_size
def getVersionCacheSize(self):
return self._version_cache_size
def getVersionPoolSize(self): return self._version_pool_size def getVersionPoolSize(self):
return self._version_pool_size
def importFile(self, file): def importFile(self, file):
raise 'Not yet implemented' raise 'Not yet implemented'
...@@ -322,7 +330,8 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -322,7 +330,8 @@ class DB(UndoLogCompatible.UndoLogCompatible):
cache[h]=oid, v cache[h]=oid, v
return v return v
def objectCount(self): return len(self._storage) def objectCount(self):
return len(self._storage)
def open(self, version='', transaction=None, temporary=0, force=None, def open(self, version='', transaction=None, temporary=0, force=None,
waitflag=1): waitflag=1):
...@@ -361,9 +370,7 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -361,9 +370,7 @@ class DB(UndoLogCompatible.UndoLogCompatible):
# a one-use connection. # a one-use connection.
c=self.klass( c=self.klass(
version=version, version=version,
cache_size=self._version_cache_size, cache_size=self._version_cache_size)
cache_deactivate_after=
self._version_cache_deactivate_after)
c._setDB(self) c._setDB(self)
self._temps.append(c) self._temps.append(c)
if transaction is not None: transaction[id(c)]=c if transaction is not None: transaction[id(c)]=c
...@@ -412,17 +419,13 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -412,17 +419,13 @@ class DB(UndoLogCompatible.UndoLogCompatible):
if self._version_pool_size > len(allocated) or force: if self._version_pool_size > len(allocated) or force:
c=self.klass( c=self.klass(
version=version, version=version,
cache_size=self._version_cache_size, cache_size=self._version_cache_size)
cache_deactivate_after=
self._version_cache_deactivate_after)
allocated.append(c) allocated.append(c)
pool.append(c) pool.append(c)
elif self._pool_size > len(allocated) or force: elif self._pool_size > len(allocated) or force:
c=self.klass( c=self.klass(
version=version, version=version,
cache_size=self._cache_size, cache_size=self._cache_size)
cache_deactivate_after=
self._cache_deactivate_after)
allocated.append(c) allocated.append(c)
pool.append(c) pool.append(c)
...@@ -492,19 +495,26 @@ class DB(UndoLogCompatible.UndoLogCompatible): ...@@ -492,19 +495,26 @@ class DB(UndoLogCompatible.UndoLogCompatible):
raise raise
def setCacheDeactivateAfter(self, v): def setCacheDeactivateAfter(self, v):
self._cache_deactivate_after=v self._cache_deactivate_after = v
for c in self._pools[0][''][1]: d = self._pools[0]
c._cache.cache_age=v pool_info = d.get('')
if pool_info is not None:
for c in pool_info[1]:
c._cache.cache_age = v
def setCacheSize(self, v): def setCacheSize(self, v):
self._cache_size=v self._cache_size = v
for c in self._pools[0][''][1]: d = self._pools[0]
c._cache.cache_size=v pool_info = d.get('')
if pool_info is not None:
for c in pool_info[1]:
c._cache.cache_size = v
def setClassFactory(self, factory): def setClassFactory(self, factory):
self._classFactory=factory self._classFactory = factory
def setPoolSize(self, v): self._pool_size=v def setPoolSize(self, v):
self._pool_size=v
def setVersionCacheDeactivateAfter(self, v): def setVersionCacheDeactivateAfter(self, v):
self._version_cache_deactivate_after=v self._version_cache_deactivate_after=v
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.58 2002/04/05 01:12:48 jeremy Exp $\n"; "$Id: cPersistence.c,v 1.59 2002/04/15 18:42:51 jeremy Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
return -1; return -1;
if (*name == '_' && name[1] == 'p' && name[2] == '_') { if (*name == '_' && name[1] == 'p' && name[2] == '_') {
if (name[3] == 'o' && name[4] == 'i' && name[5] == 'd' && ! name[6]) { if (strcmp(name + 3, "oid") == 0) {
if (self->cache) { if (self->cache) {
int result; int result;
if (v == NULL) { if (v == NULL) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not delete the oid of a cached object"); "can not delete oid of cached object");
return -1; return -1;
} }
if (PyObject_Cmp(self->oid, v, &result) < 0) if (PyObject_Cmp(self->oid, v, &result) < 0)
return -1; return -1;
if (result) { if (result) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not change the oid of a cached object"); "can not change oid of cached object");
return -1; return -1;
} }
} }
...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
ASSIGN(self->oid, v); ASSIGN(self->oid, v);
return 0; return 0;
} }
if (name[3]=='j' && name[4]=='a' && name[5]=='r' && ! name[6]) else if (strcmp(name + 3, "jar") == 0) {
{ if (self->cache && self->jar) {
int result;
if (v == NULL) {
PyErr_SetString(PyExc_ValueError,
"can not delete jar of cached object");
return -1;
}
if (PyObject_Cmp(self->jar, v, &result) < 0)
return -1;
if (result) {
PyErr_SetString(PyExc_ValueError,
"can not change jar of cached object");
return -1;
}
}
Py_XINCREF(v); Py_XINCREF(v);
ASSIGN(self->jar, v); ASSIGN(self->jar, v);
return 0; return 0;
} }
if (name[3]=='s' && strcmp(name+4,"erial")==0) else if (strcmp(name + 3, "serial") == 0) {
{ if (v) {
if (v) if (PyString_Check(v) && PyString_GET_SIZE(v) == 8)
{ memcpy(self->serial, PyString_AS_STRING(v), 8);
if (PyString_Check(v) && PyString_Size(v)==8) else {
memcpy(self->serial, PyString_AS_STRING(v), 8);
else
{
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"_p_serial must be an 8-character string"); "_p_serial must be an 8-character string");
return -1; return -1;
} }
} } else
else memset(self->serial, 0, 8);
memset(self->serial, 0, 8);
return 0; return 0;
} }
if (name[3]=='c' && strcmp(name+4,"hanged")==0) else if (strcmp(name+3, "changed") == 0) {
{ if (!v)
if (! v)
{ {
/* delatter is used to invalidate the object /* delatter is used to invalidate the object
*even* if it has changed. *even* if it has changed.
......
...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them. ...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them.
static char cPickleCache_doc_string[] = static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n" "Defines the PickleCache used by ZODB Connection objects.\n"
"\n" "\n"
"$Id: cPickleCache.c,v 1.57 2002/04/15 15:17:33 chrisw Exp $\n"; "$Id: cPickleCache.c,v 1.58 2002/04/15 18:42:51 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;} #define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E)) #define UNLESS(E) if(!(E))
...@@ -150,7 +150,9 @@ typedef struct { ...@@ -150,7 +150,9 @@ typedef struct {
} ccobject; } ccobject;
#ifdef MUCH_RING_CHECKING
static int present_in_ring(ccobject *self, CPersistentRing *target); static int present_in_ring(ccobject *self, CPersistentRing *target);
#endif
static int ring_corrupt(ccobject *self, const char *context); static int ring_corrupt(ccobject *self, const char *context);
static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v); static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v);
...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context) ...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context)
static int static int
scan_gc_items(ccobject *self,int target) scan_gc_items(ccobject *self,int target)
{ {
/* This function must only be called with the ring lock held */ /* This function must only be called with the ring lock held,
because it places a non-object placeholder in the ring.
*/
cPersistentObject *object; cPersistentObject *object;
int error; int error;
...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid) ...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid)
return 0; return 0;
} }
static PyObject *
cc_ringlen(ccobject *self, PyObject *args)
{
CPersistentRing *here;
int c = 0;
if (!PyArg_ParseTuple(args, ":ringlen"))
return NULL;
for (here = self->ring_home.next; here != &self->ring_home;
here = here->next)
c++;
return PyInt_FromLong(c);
}
static struct PyMethodDef cc_methods[] = { static struct PyMethodDef cc_methods[] = {
{"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS, {"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS,
...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = { ...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = {
"invalidate(oids) -- invalidate one, many, or all ids"}, "invalidate(oids) -- invalidate one, many, or all ids"},
{"get", (PyCFunction)cc_get, METH_VARARGS, {"get", (PyCFunction)cc_get, METH_VARARGS,
"get(key [, default]) -- get an item, or a default"}, "get(key [, default]) -- get an item, or a default"},
{"ringlen", (PyCFunction)cc_ringlen, METH_VARARGS,
"ringlen() -- Returns number of non-ghost items in cache."},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
cPersistentObject *p; cPersistentObject *p;
if (!PyExtensionInstance_Check(v)) { if (!PyExtensionInstance_Check(v)) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
return -1; return -1;
} }
class = (PyExtensionClass *)(v->ob_type); class = (PyExtensionClass *)(v->ob_type);
if (!((class->class_flags & PERSISTENT_TYPE_FLAG) if (!((class->class_flags & PERSISTENT_TYPE_FLAG)
&& v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) { && v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
/* Must be either persistent classes (ie ZClasses), or instances /* Must be either persistent classes (ie ZClasses), or instances
of persistent classes (ie Python classeses that derive from of persistent classes (ie Python classeses that derive from
...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
* persistent class. * persistent class.
*/ */
oid = PyObject_GetAttr(v, py__p_oid); oid = PyObject_GetAttr(v, py__p_oid);
if (oid == NULL) if (oid == NULL)
return -1; return -1;
/* XXX key and oid should both be PyString objects. /* XXX key and oid should both be PyString objects.
...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
return -1; return -1;
} }
/* XXX check that object has valid _p_jar? */
object_again = object_from_oid(self, key); object_again = object_from_oid(self, key);
if (object_again) { if (object_again) {
if (object_again != v) { if (object_again != v) {
...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key) ...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key)
if (PyDict_DelItem(self->data, key) < 0) { if (PyDict_DelItem(self->data, key) < 0) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"unexpectedly couldnt remove key in cc_ass_sub"); "unexpectedly couldn't remove key in cc_ass_sub");
return -1; return -1;
} }
...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context) ...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context)
if (here->next->prev != here) if (here->next->prev != here)
return 10; return 10;
if (!self->ring_lock) { if (!self->ring_lock) {
/* if the ring must be locked then it only contains object other than persistent instances */ /* If the ring must be locked, then it only contains
object other than persistent instances.
*/
if (here != &self->ring_home) { if (here != &self->ring_home) {
cPersistentObject *object = object_from_ring(self, here, cPersistentObject *object = object_from_ring(self, here,
context); context);
...@@ -986,17 +1008,19 @@ static int ...@@ -986,17 +1008,19 @@ static int
ring_corrupt(ccobject *self, const char *context) ring_corrupt(ccobject *self, const char *context)
{ {
#ifdef MUCH_RING_CHECKING #ifdef MUCH_RING_CHECKING
int code = _ring_corrupt(self,context); int code = _ring_corrupt(self, context);
if (code) { if (code) {
PyErr_Format(PyExc_RuntimeError, if (!PyErr_Occurred())
"broken ring (code %d) in %s, size %d", PyErr_Format(PyExc_RuntimeError,
code, context, PyDict_Size(self->data)); "broken ring (code %d) in %s, size %d",
code, context, PyDict_Size(self->data));
return code; return code;
} }
#endif #endif
return 0; return 0;
} }
#ifdef MUCH_RING_CHECKING
static int static int
present_in_ring(ccobject *self,CPersistentRing *target) present_in_ring(ccobject *self,CPersistentRing *target)
{ {
...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target) ...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target)
here = here->next; here = here->next;
} }
} }
#endif
static PyMappingMethods cc_as_mapping = { static PyMappingMethods cc_as_mapping = {
(inquiry)cc_length, /*mp_length*/ (inquiry)cc_length, /*mp_length*/
...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = { ...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = {
}; };
static ccobject * static ccobject *
newccobject(PyObject *jar, int cache_size, int cache_age) newccobject(PyObject *jar, int cache_size)
{ {
ccobject *self; ccobject *self;
...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age) ...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age)
static PyObject * static PyObject *
cCM_new(PyObject *self, PyObject *args) cCM_new(PyObject *self, PyObject *args)
{ {
int cache_size=100, cache_age=1000; int cache_size=100;
PyObject *jar; PyObject *jar;
if (!PyArg_ParseTuple(args, "O|ii", &jar, &cache_size, &cache_age)) if (!PyArg_ParseTuple(args, "O|i", &jar, &cache_size))
return NULL; return NULL;
return (PyObject*)newccobject(jar, cache_size, cache_age); return (PyObject*)newccobject(jar, cache_size);
} }
static struct PyMethodDef cCM_methods[] = { static struct PyMethodDef cCM_methods[] = {
{"PickleCache",(PyCFunction)cCM_new, METH_VARARGS, ""}, {"PickleCache", (PyCFunction)cCM_new, METH_VARARGS, ""},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.58 2002/04/05 01:12:48 jeremy Exp $\n"; "$Id: cPersistence.c,v 1.59 2002/04/15 18:42:51 jeremy Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -572,19 +572,19 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
return -1; return -1;
if (*name == '_' && name[1] == 'p' && name[2] == '_') { if (*name == '_' && name[1] == 'p' && name[2] == '_') {
if (name[3] == 'o' && name[4] == 'i' && name[5] == 'd' && ! name[6]) { if (strcmp(name + 3, "oid") == 0) {
if (self->cache) { if (self->cache) {
int result; int result;
if (v == NULL) { if (v == NULL) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not delete the oid of a cached object"); "can not delete oid of cached object");
return -1; return -1;
} }
if (PyObject_Cmp(self->oid, v, &result) < 0) if (PyObject_Cmp(self->oid, v, &result) < 0)
return -1; return -1;
if (result) { if (result) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"can not change the oid of a cached object"); "can not change oid of cached object");
return -1; return -1;
} }
} }
...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -592,32 +592,41 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
ASSIGN(self->oid, v); ASSIGN(self->oid, v);
return 0; return 0;
} }
if (name[3]=='j' && name[4]=='a' && name[5]=='r' && ! name[6]) else if (strcmp(name + 3, "jar") == 0) {
{ if (self->cache && self->jar) {
int result;
if (v == NULL) {
PyErr_SetString(PyExc_ValueError,
"can not delete jar of cached object");
return -1;
}
if (PyObject_Cmp(self->jar, v, &result) < 0)
return -1;
if (result) {
PyErr_SetString(PyExc_ValueError,
"can not change jar of cached object");
return -1;
}
}
Py_XINCREF(v); Py_XINCREF(v);
ASSIGN(self->jar, v); ASSIGN(self->jar, v);
return 0; return 0;
} }
if (name[3]=='s' && strcmp(name+4,"erial")==0) else if (strcmp(name + 3, "serial") == 0) {
{ if (v) {
if (v) if (PyString_Check(v) && PyString_GET_SIZE(v) == 8)
{ memcpy(self->serial, PyString_AS_STRING(v), 8);
if (PyString_Check(v) && PyString_Size(v)==8) else {
memcpy(self->serial, PyString_AS_STRING(v), 8);
else
{
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"_p_serial must be an 8-character string"); "_p_serial must be an 8-character string");
return -1; return -1;
} }
} } else
else memset(self->serial, 0, 8);
memset(self->serial, 0, 8);
return 0; return 0;
} }
if (name[3]=='c' && strcmp(name+4,"hanged")==0) else if (strcmp(name+3, "changed") == 0) {
{ if (!v)
if (! v)
{ {
/* delatter is used to invalidate the object /* delatter is used to invalidate the object
*even* if it has changed. *even* if it has changed.
......
...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them. ...@@ -88,7 +88,7 @@ process must skip such objects, rather than deactivating them.
static char cPickleCache_doc_string[] = static char cPickleCache_doc_string[] =
"Defines the PickleCache used by ZODB Connection objects.\n" "Defines the PickleCache used by ZODB Connection objects.\n"
"\n" "\n"
"$Id: cPickleCache.c,v 1.57 2002/04/15 15:17:33 chrisw Exp $\n"; "$Id: cPickleCache.c,v 1.58 2002/04/15 18:42:51 jeremy Exp $\n";
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;} #define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E)) #define UNLESS(E) if(!(E))
...@@ -150,7 +150,9 @@ typedef struct { ...@@ -150,7 +150,9 @@ typedef struct {
} ccobject; } ccobject;
#ifdef MUCH_RING_CHECKING
static int present_in_ring(ccobject *self, CPersistentRing *target); static int present_in_ring(ccobject *self, CPersistentRing *target);
#endif
static int ring_corrupt(ccobject *self, const char *context); static int ring_corrupt(ccobject *self, const char *context);
static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v); static int cc_ass_sub(ccobject *self, PyObject *key, PyObject *v);
...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context) ...@@ -214,7 +216,9 @@ object_from_ring(ccobject *self, CPersistentRing *here, const char *context)
static int static int
scan_gc_items(ccobject *self,int target) scan_gc_items(ccobject *self,int target)
{ {
/* This function must only be called with the ring lock held */ /* This function must only be called with the ring lock held,
because it places a non-object placeholder in the ring.
*/
cPersistentObject *object; cPersistentObject *object;
int error; int error;
...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid) ...@@ -632,6 +636,19 @@ cc_oid_unreferenced(ccobject *self, PyObject *oid)
return 0; return 0;
} }
static PyObject *
cc_ringlen(ccobject *self, PyObject *args)
{
CPersistentRing *here;
int c = 0;
if (!PyArg_ParseTuple(args, ":ringlen"))
return NULL;
for (here = self->ring_home.next; here != &self->ring_home;
here = here->next)
c++;
return PyInt_FromLong(c);
}
static struct PyMethodDef cc_methods[] = { static struct PyMethodDef cc_methods[] = {
{"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS, {"lru_items", (PyCFunction)cc_lru_items, METH_VARARGS,
...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = { ...@@ -658,6 +675,8 @@ static struct PyMethodDef cc_methods[] = {
"invalidate(oids) -- invalidate one, many, or all ids"}, "invalidate(oids) -- invalidate one, many, or all ids"},
{"get", (PyCFunction)cc_get, METH_VARARGS, {"get", (PyCFunction)cc_get, METH_VARARGS,
"get(key [, default]) -- get an item, or a default"}, "get(key [, default]) -- get an item, or a default"},
{"ringlen", (PyCFunction)cc_ringlen, METH_VARARGS,
"ringlen() -- Returns number of non-ghost items in cache."},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -771,14 +790,14 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
cPersistentObject *p; cPersistentObject *p;
if (!PyExtensionInstance_Check(v)) { if (!PyExtensionInstance_Check(v)) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
return -1; return -1;
} }
class = (PyExtensionClass *)(v->ob_type); class = (PyExtensionClass *)(v->ob_type);
if (!((class->class_flags & PERSISTENT_TYPE_FLAG) if (!((class->class_flags & PERSISTENT_TYPE_FLAG)
&& v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) { && v->ob_type->tp_basicsize >= sizeof(cPersistentObject))) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_TypeError,
"Cache values must be persistent objects."); "Cache values must be persistent objects.");
/* Must be either persistent classes (ie ZClasses), or instances /* Must be either persistent classes (ie ZClasses), or instances
of persistent classes (ie Python classeses that derive from of persistent classes (ie Python classeses that derive from
...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -790,7 +809,6 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
* persistent class. * persistent class.
*/ */
oid = PyObject_GetAttr(v, py__p_oid); oid = PyObject_GetAttr(v, py__p_oid);
if (oid == NULL) if (oid == NULL)
return -1; return -1;
/* XXX key and oid should both be PyString objects. /* XXX key and oid should both be PyString objects.
...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v) ...@@ -806,6 +824,8 @@ cc_add_item(ccobject *self, PyObject *key, PyObject *v)
return -1; return -1;
} }
/* XXX check that object has valid _p_jar? */
object_again = object_from_oid(self, key); object_again = object_from_oid(self, key);
if (object_again) { if (object_again) {
if (object_again != v) { if (object_again != v) {
...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key) ...@@ -911,7 +931,7 @@ cc_del_item(ccobject *self, PyObject *key)
if (PyDict_DelItem(self->data, key) < 0) { if (PyDict_DelItem(self->data, key) < 0) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"unexpectedly couldnt remove key in cc_ass_sub"); "unexpectedly couldn't remove key in cc_ass_sub");
return -1; return -1;
} }
...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context) ...@@ -958,7 +978,9 @@ _ring_corrupt(ccobject *self, const char *context)
if (here->next->prev != here) if (here->next->prev != here)
return 10; return 10;
if (!self->ring_lock) { if (!self->ring_lock) {
/* if the ring must be locked then it only contains object other than persistent instances */ /* If the ring must be locked, then it only contains
object other than persistent instances.
*/
if (here != &self->ring_home) { if (here != &self->ring_home) {
cPersistentObject *object = object_from_ring(self, here, cPersistentObject *object = object_from_ring(self, here,
context); context);
...@@ -986,17 +1008,19 @@ static int ...@@ -986,17 +1008,19 @@ static int
ring_corrupt(ccobject *self, const char *context) ring_corrupt(ccobject *self, const char *context)
{ {
#ifdef MUCH_RING_CHECKING #ifdef MUCH_RING_CHECKING
int code = _ring_corrupt(self,context); int code = _ring_corrupt(self, context);
if (code) { if (code) {
PyErr_Format(PyExc_RuntimeError, if (!PyErr_Occurred())
"broken ring (code %d) in %s, size %d", PyErr_Format(PyExc_RuntimeError,
code, context, PyDict_Size(self->data)); "broken ring (code %d) in %s, size %d",
code, context, PyDict_Size(self->data));
return code; return code;
} }
#endif #endif
return 0; return 0;
} }
#ifdef MUCH_RING_CHECKING
static int static int
present_in_ring(ccobject *self,CPersistentRing *target) present_in_ring(ccobject *self,CPersistentRing *target)
{ {
...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target) ...@@ -1009,6 +1033,7 @@ present_in_ring(ccobject *self,CPersistentRing *target)
here = here->next; here = here->next;
} }
} }
#endif
static PyMappingMethods cc_as_mapping = { static PyMappingMethods cc_as_mapping = {
(inquiry)cc_length, /*mp_length*/ (inquiry)cc_length, /*mp_length*/
...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = { ...@@ -1038,7 +1063,7 @@ static PyTypeObject Cctype = {
}; };
static ccobject * static ccobject *
newccobject(PyObject *jar, int cache_size, int cache_age) newccobject(PyObject *jar, int cache_size)
{ {
ccobject *self; ccobject *self;
...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age) ...@@ -1071,16 +1096,16 @@ newccobject(PyObject *jar, int cache_size, int cache_age)
static PyObject * static PyObject *
cCM_new(PyObject *self, PyObject *args) cCM_new(PyObject *self, PyObject *args)
{ {
int cache_size=100, cache_age=1000; int cache_size=100;
PyObject *jar; PyObject *jar;
if (!PyArg_ParseTuple(args, "O|ii", &jar, &cache_size, &cache_age)) if (!PyArg_ParseTuple(args, "O|i", &jar, &cache_size))
return NULL; return NULL;
return (PyObject*)newccobject(jar, cache_size, cache_age); return (PyObject*)newccobject(jar, cache_size);
} }
static struct PyMethodDef cCM_methods[] = { static struct PyMethodDef cCM_methods[] = {
{"PickleCache",(PyCFunction)cCM_new, METH_VARARGS, ""}, {"PickleCache", (PyCFunction)cCM_new, METH_VARARGS, ""},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
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