Commit 6f4d372f authored by Jim Fulton's avatar Jim Fulton

Applied the patch (slightly modified) from

https://bugs.launchpad.net/zodb/+bug/533015

Much thanks to Hanno Schlichting and Nikolay Kim for coming up with
the patch.
parent 09f8dcd7
...@@ -662,10 +662,24 @@ class EstimatedSizeTests(ZODB.tests.util.TestCase): ...@@ -662,10 +662,24 @@ class EstimatedSizeTests(ZODB.tests.util.TestCase):
# sanity check # sanity check
self.assert_(cache.total_estimated_size >= 0) self.assert_(cache.total_estimated_size >= 0)
def test_cache_garbage_collection_shrinking_object(self):
db = self.db
# activate size based cache garbage collection
db.setCacheSizeBytes(1000)
obj, conn, cache = self.obj, self.conn, self.conn._cache
# verify the change worked as expected
self.assertEqual(cache.cache_size_bytes, 1000)
# verify our entrance assumption is fullfilled
self.assert_(cache.total_estimated_size > 1)
# give the objects some size
obj.setValueWithSize(500)
transaction.savepoint()
self.assert_(cache.total_estimated_size > 500)
# make the object smaller
obj.setValueWithSize(100)
transaction.savepoint()
# make sure there was no overflow
self.assert_(cache.total_estimated_size != 0)
# ---- stubs # ---- stubs
......
...@@ -668,7 +668,8 @@ cc_update_object_size_estimation(ccobject *self, PyObject *args) ...@@ -668,7 +668,8 @@ cc_update_object_size_estimation(ccobject *self, PyObject *args)
PyObject *oid; PyObject *oid;
cPersistentObject *v; cPersistentObject *v;
unsigned int new_size; unsigned int new_size;
if (!PyArg_ParseTuple(args, "OI:updateObjectSizeEstimation", &oid, &new_size)) if (!PyArg_ParseTuple(args, "OI:updateObjectSizeEstimation",
&oid, &new_size))
return NULL; return NULL;
/* Note: reference borrowed */ /* Note: reference borrowed */
v = (cPersistentObject *)PyDict_GetItem(self->data, oid); v = (cPersistentObject *)PyDict_GetItem(self->data, oid);
...@@ -680,7 +681,8 @@ cc_update_object_size_estimation(ccobject *self, PyObject *args) ...@@ -680,7 +681,8 @@ cc_update_object_size_estimation(ccobject *self, PyObject *args)
if (v->ring.r_next) if (v->ring.r_next)
{ {
self->total_estimated_size += _estimated_size_in_bytes( self->total_estimated_size += _estimated_size_in_bytes(
_estimated_size_in_24_bits(new_size) - v->estimated_size (int)(_estimated_size_in_24_bits(new_size))
- (int)(v->estimated_size)
); );
/* we do this in "Connection" as we need it even when the /* we do this in "Connection" as we need it even when the
object is not in the cache (or not the ring) object is not in the cache (or not the ring)
......
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