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,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