Make LRU cache not default to treecache & add options to use it

This commit is contained in:
David Baker 2016-01-22 12:10:33 +00:00
parent 5b142788d2
commit 10f76dc5da
4 changed files with 29 additions and 19 deletions

View File

@ -53,7 +53,7 @@ class EventPushActionsStore(SQLBaseStore):
f, 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( def get_unread_event_push_actions_by_room_for_user(
self, room_id, user_id, last_read_event_id self, room_id, user_id, last_read_event_id
): ):

View File

@ -17,6 +17,7 @@ import logging
from synapse.util.async import ObservableDeferred from synapse.util.async import ObservableDeferred
from synapse.util import unwrapFirstError from synapse.util import unwrapFirstError
from synapse.util.caches.lrucache import LruCache from synapse.util.caches.lrucache import LruCache
from synapse.util.caches.treecache import TreeCache
from . import caches_by_name, DEBUG_CACHES, cache_counter from . import caches_by_name, DEBUG_CACHES, cache_counter
@ -36,9 +37,12 @@ _CacheSentinel = object()
class Cache(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: 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 self.max_entries = None
else: else:
self.cache = OrderedDict() self.cache = OrderedDict()
@ -131,7 +135,7 @@ class CacheDescriptor(object):
which can be used to insert values into the cache specifically, without which can be used to insert values into the cache specifically, without
calling the calculation function. 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): inlineCallbacks=False):
self.orig = orig self.orig = orig
@ -143,6 +147,7 @@ class CacheDescriptor(object):
self.max_entries = max_entries self.max_entries = max_entries
self.num_args = num_args self.num_args = num_args
self.lru = lru self.lru = lru
self.tree = tree
self.arg_names = inspect.getargspec(orig).args[1:num_args+1] self.arg_names = inspect.getargspec(orig).args[1:num_args+1]
@ -158,6 +163,7 @@ class CacheDescriptor(object):
max_entries=self.max_entries, max_entries=self.max_entries,
keylen=self.num_args, keylen=self.num_args,
lru=self.lru, lru=self.lru,
tree=self.tree,
) )
def __get__(self, obj, objtype=None): def __get__(self, obj, objtype=None):
@ -331,21 +337,23 @@ class CacheListDescriptor(object):
return wrapped 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
)
def cachedInlineCallbacks(max_entries=1000, num_args=1, lru=False):
return lambda orig: CacheDescriptor( return lambda orig: CacheDescriptor(
orig, orig,
max_entries=max_entries, max_entries=max_entries,
num_args=num_args, num_args=num_args,
lru=lru, lru=lru,
tree=tree,
)
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, inlineCallbacks=True,
) )

View File

@ -17,8 +17,6 @@
from functools import wraps from functools import wraps
import threading import threading
from synapse.util.caches.treecache import TreeCache
def enumerate_leaves(node, depth): def enumerate_leaves(node, depth):
if depth == 0: if depth == 0:
@ -31,8 +29,8 @@ def enumerate_leaves(node, depth):
class LruCache(object): class LruCache(object):
"""Least-recently-used cache.""" """Least-recently-used cache."""
def __init__(self, max_size, keylen): def __init__(self, max_size, keylen, cache_type=dict):
cache = TreeCache() cache = cache_type()
self.size = 0 self.size = 0
list_root = [] list_root = []
list_root[:] = [list_root, list_root, None, None] list_root[:] = [list_root, list_root, None, None]
@ -124,6 +122,9 @@ class LruCache(object):
@synchronized @synchronized
def cache_del_multi(key): def cache_del_multi(key):
"""
This will only work if constructed with cache_type=TreeCache
"""
popped = cache.pop(key) popped = cache.pop(key)
if popped is None: if popped is None:
return return

View File

@ -17,6 +17,7 @@
from .. import unittest from .. import unittest
from synapse.util.caches.lrucache import LruCache from synapse.util.caches.lrucache import LruCache
from synapse.util.caches.treecache import TreeCache
class LruCacheTestCase(unittest.TestCase): class LruCacheTestCase(unittest.TestCase):
@ -54,7 +55,7 @@ class LruCacheTestCase(unittest.TestCase):
self.assertEquals(cache.pop(("key",)), None) self.assertEquals(cache.pop(("key",)), None)
def test_del_multi(self): def test_del_multi(self):
cache = LruCache(4, 2) cache = LruCache(4, 2, cache_type=TreeCache)
cache[("animal", "cat")] = "mew" cache[("animal", "cat")] = "mew"
cache[("animal", "dog")] = "woof" cache[("animal", "dog")] = "woof"
cache[("vehicles", "car")] = "vroom" cache[("vehicles", "car")] = "vroom"