diff --git a/synapse/util/caches/__init__.py b/synapse/util/caches/__init__.py
index 9d450fade5..838cec45fe 100644
--- a/synapse/util/caches/__init__.py
+++ b/synapse/util/caches/__init__.py
@@ -15,6 +15,9 @@
import synapse.metrics
from lrucache import LruCache
+import os
+
+CACHE_SIZE_FACTOR = float(os.environ.get("SYNAPSE_CACHE_FACTOR", 0.1))
DEBUG_CACHES = False
@@ -27,9 +30,62 @@ cache_counter = metrics.register_cache(
labels=["name"],
)
-_string_cache = LruCache(5000)
+_string_cache = LruCache(int(5000 * CACHE_SIZE_FACTOR))
caches_by_name["string_cache"] = _string_cache
+KNOWN_KEYS = {
+ key: key for key in
+ (
+ "auth_events",
+ "content",
+ "depth",
+ "event_id",
+ "hashes",
+ "origin",
+ "origin_server_ts",
+ "prev_events",
+ "room_id",
+ "sender",
+ "signatures",
+ "state_key",
+ "type",
+ "unsigned",
+ "user_id",
+ )
+}
+
+
def intern_string(string):
+ """Takes a (potentially) unicode string and interns using custom cache
+ """
return _string_cache.setdefault(string, string)
+
+
+def intern_dict(dictionary):
+ """Takes a dictionary and interns well known keys and their values
+ """
+ return _intern_known_values({
+ _intern_key(key): value for key, value in dictionary.items()
+ })
+
+
+def _intern_known_values(dictionary):
+ intern_str_keys = ("event_id", "room_id")
+ intern_unicode_keys = ("sender", "user_id", "type", "state_key")
+
+ for key in intern_str_keys:
+ val = dictionary.get(key, None)
+ if val is not None:
+ dictionary[key] = intern(val.encode('ascii'))
+
+ for key in intern_unicode_keys:
+ val = dictionary.get(key, None)
+ if val is not None:
+ dictionary[key] = intern_string(val)
+
+ return dictionary
+
+
+def _intern_key(key):
+ return KNOWN_KEYS.get(key, key)
|