summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2016-03-22 18:22:52 +0000
committerErik Johnston <erik@matrix.org>2016-03-23 14:53:53 +0000
commit75daede92f041500347a5f446229be5ca50c2b8e (patch)
treefe29a801a1f5fdbe12424846f1c2052135c49fad
parentMerge pull request #664 from matrix-org/erikj/public_room_list (diff)
downloadsynapse-75daede92f041500347a5f446229be5ca50c2b8e.tar.xz
String intern
-rw-r--r--synapse/storage/state.py12
-rw-r--r--synapse/util/caches/__init__.py8
2 files changed, 17 insertions, 3 deletions
diff --git a/synapse/storage/state.py b/synapse/storage/state.py
index eab2c5a8ce..1982b1c607 100644
--- a/synapse/storage/state.py
+++ b/synapse/storage/state.py
@@ -15,6 +15,7 @@
 
 from ._base import SQLBaseStore
 from synapse.util.caches.descriptors import cached, cachedList
+from synapse.util.caches import intern_string
 
 from twisted.internet import defer
 
@@ -155,7 +156,9 @@ class StateStore(SQLBaseStore):
 
     @defer.inlineCallbacks
     def get_current_state_for_key(self, room_id, event_type, state_key):
-        event_ids = yield self._get_current_state_for_key(room_id, event_type, state_key)
+        event_ids = yield self._get_current_state_for_key(
+            room_id, intern_string(event_type), intern_string(state_key)
+        )
         events = yield self._get_events(event_ids, get_prev_content=False)
         defer.returnValue(events)
 
@@ -202,7 +205,7 @@ class StateStore(SQLBaseStore):
 
             results = {}
             for row in rows:
-                key = (row["type"], row["state_key"])
+                key = (intern_string(row["type"]), intern_string(row["state_key"]))
                 results.setdefault(row["state_group"], {})[key] = row["event_id"]
             return results
 
@@ -393,7 +396,10 @@ class StateStore(SQLBaseStore):
                     # cache absence of the key, on the assumption that if we've
                     # explicitly asked for some types then we will probably ask
                     # for them again.
-                    state_dict = {key: None for key in types}
+                    state_dict = {
+                        (intern_string(etype), intern_string(state_key)): None
+                        for (etype, state_key) in types
+                    }
                     state_dict.update(results[group])
                     results[group] = state_dict
                 else:
diff --git a/synapse/util/caches/__init__.py b/synapse/util/caches/__init__.py
index 1a14904194..9d450fade5 100644
--- a/synapse/util/caches/__init__.py
+++ b/synapse/util/caches/__init__.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 import synapse.metrics
+from lrucache import LruCache
 
 DEBUG_CACHES = False
 
@@ -25,3 +26,10 @@ cache_counter = metrics.register_cache(
     lambda: {(name,): len(caches_by_name[name]) for name in caches_by_name.keys()},
     labels=["name"],
 )
+
+_string_cache = LruCache(5000)
+caches_by_name["string_cache"] = _string_cache
+
+
+def intern_string(string):
+    return _string_cache.setdefault(string, string)