[Zodb-checkins] CVS: StandaloneZODB/ZODB - cPickleCache.c:1.56
Jeremy Hylton
jeremy@zope.com
Fri, 12 Apr 2002 18:16:21 -0400
Update of /cvs-repository/StandaloneZODB/ZODB
In directory cvs.zope.org:/tmp/cvs-serv9394
Modified Files:
cPickleCache.c
Log Message:
Sundry changes.
Implement behavior for minimize() and full_sweep() as discussed on
zodb-dev. minimize() ghostifies all unmodified objects. full_sweep()
with age==0 is the same as minimize(), otherwise it's the same as
incrgc().
Reformat and/or reindent lots of code.
Use PyObject_Compare() instead of PyObject_Cmp() because it has a
simpler return value.
Fix a few more PyDict_SetItem() and PyDict_DelItem() calls to make
correct check for error return.
=== StandaloneZODB/ZODB/cPickleCache.c 1.55 => 1.56 ===
#ifdef MUCH_RING_CHECKING
- int safety_counter = self->cache_size*10;
- if (safety_counter<10000)
+ int safety_counter = self->cache_size * 10;
+ if (safety_counter < 10000)
safety_counter = 10000;
#endif
@@ -368,29 +368,25 @@
return lockgc(self, target_size);
}
-/* XXX Does it make sense for full_sweep() and reallyfull_sweep() to
- empty the cache completely? I agree that it would if dt is 0, but
- don't think it should for other times. Perhaps it should just call
- incrgc() if dt > 2; the new cache may be efficient enough that
- incrgc() would suffice.
-*/
-
static PyObject *
cc_full_sweep(ccobject *self, PyObject *args)
{
int dt = 0;
if (!PyArg_ParseTuple(args, "|i:full_sweep", &dt))
return NULL;
- return lockgc(self, 0);
+ if (dt == 0)
+ return lockgc(self, 0);
+ else
+ return cc_incrgc(self, args);
}
static PyObject *
-cc_reallyfull_sweep(ccobject *self, PyObject *args)
+cc_minimize(ccobject *self, PyObject *args)
{
- int dt = 0;
- if (!PyArg_ParseTuple(args, "|i:reallyfull_sweep", &dt))
- return NULL;
- return lockgc(self, 0);
+ int ignored;
+ if (!PyArg_ParseTuple(args, "|i:minimize", &ignored))
+ return NULL;
+ return lockgc(self, 0);
}
static void
@@ -425,67 +421,75 @@
{
PyObject *inv, *key, *v;
int i;
-
+
+ /* XXX The code supports invalidation of all objects, but I don't
+ think it's possible for a Connection object to pass None. If
+ this is correct, the code could be simplied.
+ */
+
if (PyArg_ParseTuple(args, "O!", &PyDict_Type, &inv)) {
- for (i=0; PyDict_Next(inv, &i, &key, &v); )
- if (key==Py_None)
- { /* Eek some nitwit invalidated everything! */
- for (i=0; PyDict_Next(self->data, &i, &key, &v); )
- _invalidate(self, key);
- break;
- }
- else
- _invalidate(self, key);
- PyDict_Clear(inv);
+ for (i=0; PyDict_Next(inv, &i, &key, &v); )
+ if (key == Py_None) {
+ /* Eek some nitwit invalidated everything! */
+ for (i=0; PyDict_Next(self->data, &i, &key, &v); )
+ _invalidate(self, key);
+ break;
+ }
+ else
+ _invalidate(self, key);
+ PyDict_Clear(inv);
}
else {
- PyErr_Clear();
- UNLESS (PyArg_ParseTuple(args, "O", &inv)) return NULL;
- if (PyString_Check(inv))
- _invalidate(self, inv);
- else if (inv==Py_None) /* All */
- for (i=0; PyDict_Next(self->data, &i, &key, &v); )
- _invalidate(self, key);
- else {
- int l;
-
PyErr_Clear();
- if ((l=PyObject_Length(inv)) < 0) return NULL;
- for(i=l; --i >= 0; )
- {
- UNLESS (key=PySequence_GetItem(inv, i)) return NULL;
- _invalidate(self, key);
- Py_DECREF(key);
- }
- PySequence_DelSlice(inv, 0, l);
- }
+ if (!PyArg_ParseTuple(args, "O:invalidate", &inv))
+ return NULL;
+ if (PyString_Check(inv))
+ _invalidate(self, inv);
+ else if (inv == Py_None) /* All */
+ for (i=0; PyDict_Next(self->data, &i, &key, &v); )
+ _invalidate(self, key);
+ else {
+ int l;
+
+ PyErr_Clear();
+ l = PyObject_Length(inv);
+ if (l < 0)
+ return NULL;
+ for (i=l; --i >= 0; ) {
+ key = PySequence_GetItem(inv, i);
+ if (!key)
+ return NULL;
+ _invalidate(self, key);
+ Py_DECREF(key);
+ }
+ PySequence_DelSlice(inv, 0, l);
+ }
}
-
+
Py_INCREF(Py_None);
return Py_None;
}
-
static PyObject *
cc_get(ccobject *self, PyObject *args)
{
- PyObject *r, *key, *d=0;
+ PyObject *r, *key, *d = NULL;
- if (!PyArg_ParseTuple(args, "O|O:get", &key, &d))
- return NULL;
+ if (!PyArg_ParseTuple(args, "O|O:get", &key, &d))
+ return NULL;
- r = (PyObject *)object_from_oid(self, key);
- if (!r) {
- if (d) {
- r = d;
- Py_INCREF(r);
- } else {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
- }
+ r = (PyObject *)object_from_oid(self, key);
+ if (!r) {
+ if (d) {
+ r = d;
+ Py_INCREF(r);
+ } else {
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
+ }
- return r;
+ return r;
}
static PyObject *
@@ -638,17 +642,13 @@
},
{"full_sweep", (PyCFunction)cc_full_sweep, METH_VARARGS,
"full_sweep([age]) -- Perform a full sweep of the cache\n\n"
- "Make a single pass through the cache, removing any objects that are no\n"
- "longer referenced, and deactivating enough objects to bring\n"
- "the cache under its size limit\n"
- "The optional 'age' parameter is ignored.\n"
+ "Supported for backwards compatibility. If the age argument is 0,\n"
+ "behaves like minimize(). Otherwise, behaves like incrgc()."
},
- {"minimize", (PyCFunction)cc_reallyfull_sweep, METH_VARARGS,
- "minimize([age]) -- Remove as many objects as possible\n\n"
- "Make multiple passes through the cache, removing any objects that are no\n"
- "longer referenced, and deactivating enough objects to bring the"
- " cache under its size limit\n"
- "The option 'age' parameter is ignored.\n"
+ {"minimize", (PyCFunction)cc_minimize, METH_VARARGS,
+ "minimize([ignored]) -- Remove as many objects as possible\n\n"
+ "Ghostify all objects that are not modified. Takes an optional\n"
+ "argument, but ignores it."
},
{"incrgc", (PyCFunction)cc_incrgc, METH_VARARGS,
"incrgc([n]) -- Perform incremental garbage collection\n\n"
@@ -742,24 +742,24 @@
static int
cc_length(ccobject *self)
{
- return PyObject_Length(self->data);
+ return PyObject_Length(self->data);
}
static PyObject *
cc_subscript(ccobject *self, PyObject *key)
{
- PyObject *r;
+ PyObject *r;
- if (ring_corrupt(self, "__getitem__"))
- return NULL;
+ if (ring_corrupt(self, "__getitem__"))
+ return NULL;
- r = (PyObject *)object_from_oid(self, key);
- if (r == NULL) {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
+ r = (PyObject *)object_from_oid(self, key);
+ if (r == NULL) {
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
- return r;
+ return r;
}
static int
@@ -795,16 +795,17 @@
return -1;
/* XXX key and oid should both be PyString objects.
May be helpful to check this. */
- if (PyObject_Cmp(key, oid, &result) < 0) {
+ result = PyObject_Compare(key, oid);
+ if (PyErr_Occurred()) {
Py_DECREF(oid);
return -1;
- }
+ }
Py_DECREF(oid);
if (result) {
- PyErr_SetString(PyExc_ValueError,
- "key must be the same as the object's oid attribute");
+ PyErr_SetString(PyExc_ValueError, "cache key does not match oid");
return -1;
}
+
object_again = object_from_oid(self, key);
if (object_again) {
if (object_again != v) {
@@ -818,8 +819,9 @@
return 0;
}
}
+
if (PyExtensionClass_Check(v)) {
- if (PyDict_SetItem(self->data, key, v))
+ if (PyDict_SetItem(self->data, key, v) < 0)
return -1;
self->klass_count++;
return 0;
@@ -842,7 +844,7 @@
if (ring_corrupt(self, "pre-setitem"))
return -1;
- if (PyDict_SetItem(self->data, key, v))
+ if (PyDict_SetItem(self->data, key, v) < 0)
return -1;
p = (cPersistentObject *)v;
@@ -1015,28 +1017,24 @@
};
static PyTypeObject Cctype = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "cPickleCache", /*tp_name*/
- sizeof(ccobject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)cc_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)cc_getattr, /*tp_getattr*/
- (setattrfunc)cc_setattr, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- &cc_as_mapping, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
-
- /* Space for future expansion */
- 0L,0L,0L,0L,
- ""
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "cPickleCache", /*tp_name*/
+ sizeof(ccobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)cc_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)cc_getattr, /*tp_getattr*/
+ (setattrfunc)cc_setattr, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &cc_as_mapping, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
};
static ccobject *