Skip to content
Snippets Groups Projects
Unverified Commit 1b4d5d6a authored by Patrick Cloke's avatar Patrick Cloke Committed by GitHub
Browse files

Empty iterables should count towards cache usage. (#9028)

parent 0312266e
No related branches found
No related tags found
No related merge requests found
Fix a long-standing bug where some caches could grow larger than configured.
......@@ -105,7 +105,7 @@ class DeferredCache(Generic[KT, VT]):
keylen=keylen,
cache_name=name,
cache_type=cache_type,
size_callback=(lambda d: len(d)) if iterable else None,
size_callback=(lambda d: len(d) or 1) if iterable else None,
metrics_collection_callback=metrics_cb,
apply_cache_factor_from_config=apply_cache_factor_from_config,
) # type: LruCache[KT, VT]
......
......@@ -25,13 +25,8 @@ from tests.unittest import TestCase
class DeferredCacheTestCase(TestCase):
def test_empty(self):
cache = DeferredCache("test")
failed = False
try:
with self.assertRaises(KeyError):
cache.get("foo")
except KeyError:
failed = True
self.assertTrue(failed)
def test_hit(self):
cache = DeferredCache("test")
......@@ -155,13 +150,8 @@ class DeferredCacheTestCase(TestCase):
cache.prefill(("foo",), 123)
cache.invalidate(("foo",))
failed = False
try:
with self.assertRaises(KeyError):
cache.get(("foo",))
except KeyError:
failed = True
self.assertTrue(failed)
def test_invalidate_all(self):
cache = DeferredCache("testcache")
......@@ -215,13 +205,8 @@ class DeferredCacheTestCase(TestCase):
cache.prefill(2, "two")
cache.prefill(3, "three") # 1 will be evicted
failed = False
try:
with self.assertRaises(KeyError):
cache.get(1)
except KeyError:
failed = True
self.assertTrue(failed)
cache.get(2)
cache.get(3)
......@@ -239,13 +224,55 @@ class DeferredCacheTestCase(TestCase):
cache.prefill(3, "three")
failed = False
try:
with self.assertRaises(KeyError):
cache.get(2)
except KeyError:
failed = True
self.assertTrue(failed)
cache.get(1)
cache.get(3)
def test_eviction_iterable(self):
cache = DeferredCache(
"test", max_entries=3, apply_cache_factor_from_config=False, iterable=True,
)
cache.prefill(1, ["one", "two"])
cache.prefill(2, ["three"])
# Now access 1 again, thus causing 2 to be least-recently used
cache.get(1)
# Now add an item to the cache, which evicts 2.
cache.prefill(3, ["four"])
with self.assertRaises(KeyError):
cache.get(2)
# Ensure 1 & 3 are in the cache.
cache.get(1)
cache.get(3)
# Now access 1 again, thus causing 3 to be least-recently used
cache.get(1)
# Now add an item with multiple elements to the cache
cache.prefill(4, ["five", "six"])
# Both 1 and 3 are evicted since there's too many elements.
with self.assertRaises(KeyError):
cache.get(1)
with self.assertRaises(KeyError):
cache.get(3)
# Now add another item to fill the cache again.
cache.prefill(5, ["seven"])
# Now access 4, thus causing 5 to be least-recently used
cache.get(4)
# Add an empty item.
cache.prefill(6, [])
# 5 gets evicted and replaced since an empty element counts as an item.
with self.assertRaises(KeyError):
cache.get(5)
cache.get(4)
cache.get(6)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment