summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/storage/event_push_actions.py2
-rw-r--r--synapse/util/caches/descriptors.py20
-rw-r--r--synapse/util/caches/lrucache.py9
-rw-r--r--tests/util/test_lrucache.py3
4 files changed, 22 insertions, 12 deletions
diff --git a/synapse/storage/event_push_actions.py b/synapse/storage/event_push_actions.py
index 6a212c630b..a05c4f84cf 100644
--- a/synapse/storage/event_push_actions.py
+++ b/synapse/storage/event_push_actions.py
@@ -53,7 +53,7 @@ class EventPushActionsStore(SQLBaseStore):
             f,
         )
 
-    @cachedInlineCallbacks(num_args=3, lru=True)
+    @cachedInlineCallbacks(num_args=3, lru=True, tree=True)
     def get_unread_event_push_actions_by_room_for_user(
             self, room_id, user_id, last_read_event_id
     ):
diff --git a/synapse/util/caches/descriptors.py b/synapse/util/caches/descriptors.py
index f4a2b4e590..88e56e3302 100644
--- a/synapse/util/caches/descriptors.py
+++ b/synapse/util/caches/descriptors.py
@@ -17,6 +17,7 @@ import logging
 from synapse.util.async import ObservableDeferred
 from synapse.util import unwrapFirstError
 from synapse.util.caches.lrucache import LruCache
+from synapse.util.caches.treecache import TreeCache
 
 from . import caches_by_name, DEBUG_CACHES, cache_counter
 
@@ -36,9 +37,12 @@ _CacheSentinel = object()
 
 class Cache(object):
 
-    def __init__(self, name, max_entries=1000, keylen=1, lru=True):
+    def __init__(self, name, max_entries=1000, keylen=1, lru=True, tree=False):
         if lru:
-            self.cache = LruCache(max_size=max_entries, keylen=keylen)
+            cache_type = TreeCache if tree else dict
+            self.cache = LruCache(
+                max_size=max_entries, keylen=keylen, cache_type=cache_type
+            )
             self.max_entries = None
         else:
             self.cache = OrderedDict()
@@ -131,7 +135,7 @@ class CacheDescriptor(object):
     which can be used to insert values into the cache specifically, without
     calling the calculation function.
     """
-    def __init__(self, orig, max_entries=1000, num_args=1, lru=True,
+    def __init__(self, orig, max_entries=1000, num_args=1, lru=True, tree=False,
                  inlineCallbacks=False):
         self.orig = orig
 
@@ -143,6 +147,7 @@ class CacheDescriptor(object):
         self.max_entries = max_entries
         self.num_args = num_args
         self.lru = lru
+        self.tree = tree
 
         self.arg_names = inspect.getargspec(orig).args[1:num_args+1]
 
@@ -158,6 +163,7 @@ class CacheDescriptor(object):
             max_entries=self.max_entries,
             keylen=self.num_args,
             lru=self.lru,
+            tree=self.tree,
         )
 
     def __get__(self, obj, objtype=None):
@@ -331,21 +337,23 @@ class CacheListDescriptor(object):
         return wrapped
 
 
-def cached(max_entries=1000, num_args=1, lru=True):
+def cached(max_entries=1000, num_args=1, lru=True, tree=False):
     return lambda orig: CacheDescriptor(
         orig,
         max_entries=max_entries,
         num_args=num_args,
-        lru=lru
+        lru=lru,
+        tree=tree,
     )
 
 
-def cachedInlineCallbacks(max_entries=1000, num_args=1, lru=False):
+def cachedInlineCallbacks(max_entries=1000, num_args=1, lru=False, tree=False):
     return lambda orig: CacheDescriptor(
         orig,
         max_entries=max_entries,
         num_args=num_args,
         lru=lru,
+        tree=tree,
         inlineCallbacks=True,
     )
 
diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py
index 0feceb298a..23e86ec110 100644
--- a/synapse/util/caches/lrucache.py
+++ b/synapse/util/caches/lrucache.py
@@ -17,8 +17,6 @@
 from functools import wraps
 import threading
 
-from synapse.util.caches.treecache import TreeCache
-
 
 def enumerate_leaves(node, depth):
     if depth == 0:
@@ -31,8 +29,8 @@ def enumerate_leaves(node, depth):
 
 class LruCache(object):
     """Least-recently-used cache."""
-    def __init__(self, max_size, keylen):
-        cache = TreeCache()
+    def __init__(self, max_size, keylen, cache_type=dict):
+        cache = cache_type()
         self.size = 0
         list_root = []
         list_root[:] = [list_root, list_root, None, None]
@@ -124,6 +122,9 @@ class LruCache(object):
 
         @synchronized
         def cache_del_multi(key):
+            """
+            This will only work if constructed with cache_type=TreeCache
+            """
             popped = cache.pop(key)
             if popped is None:
                 return
diff --git a/tests/util/test_lrucache.py b/tests/util/test_lrucache.py
index fca2e98983..bcad1d4258 100644
--- a/tests/util/test_lrucache.py
+++ b/tests/util/test_lrucache.py
@@ -17,6 +17,7 @@
 from .. import unittest
 
 from synapse.util.caches.lrucache import LruCache
+from synapse.util.caches.treecache import TreeCache
 
 class LruCacheTestCase(unittest.TestCase):
 
@@ -54,7 +55,7 @@ class LruCacheTestCase(unittest.TestCase):
         self.assertEquals(cache.pop(("key",)), None)
 
     def test_del_multi(self):
-        cache = LruCache(4, 2)
+        cache = LruCache(4, 2, cache_type=TreeCache)
         cache[("animal", "cat")] = "mew"
         cache[("animal", "dog")] = "woof"
         cache[("vehicles", "car")] = "vroom"