summary refs log tree commit diff
path: root/synapse/util/caches/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/util/caches/__init__.py')
-rw-r--r--synapse/util/caches/__init__.py58
1 files changed, 57 insertions, 1 deletions
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)