Commit 6f077e60 authored by Hanno Schlichting's avatar Hanno Schlichting

Forward ported r109789, r110123-110124 from 3.9 branch to trunk

parent 8d9b2578
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
Bugs Fixed Bugs Fixed
---------- ----------
- Fixed bug in cPickleCache's byte size estimation logic.
(https://bugs.launchpad.net/zodb/+bug/533015)
- When using using a ClientStorage in a Storage server, there was a - When using using a ClientStorage in a Storage server, there was a
threading bug that caused clients to get disconnected. threading bug that caused clients to get disconnected.
......
...@@ -685,10 +685,26 @@ class EstimatedSizeTests(ZODB.tests.util.TestCase): ...@@ -685,10 +685,26 @@ 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)
# the size is not larger than the allowed maximum
self.assert_(cache.total_estimated_size <= 1000)
# ---- 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,8 +681,9 @@ cc_update_object_size_estimation(ccobject *self, PyObject *args) ...@@ -680,8 +681,9 @@ 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