From 6988e2009a82dbe12f1775c5faf3ab0fe6915219 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 25 Aug 2020 12:04:40 +0100 Subject: [PATCH] Store reverse room ID-room NID mapping, consult caches when assigning NIDs --- internal/caching/cache_roomservernids.go | 26 +++++++++++++++++-- internal/caching/caches.go | 1 + internal/caching/impl_inmemorylru.go | 10 ++++++++ roomserver/storage/shared/storage.go | 32 +++++++++++++++++++++--- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/internal/caching/cache_roomservernids.go b/internal/caching/cache_roomservernids.go index 79883ca72..7cb312c95 100644 --- a/internal/caching/cache_roomservernids.go +++ b/internal/caching/cache_roomservernids.go @@ -16,6 +16,10 @@ const ( RoomServerRoomNIDsCacheName = "roomserver_room_nids" RoomServerRoomNIDsCacheMaxEntries = 1024 RoomServerRoomNIDsCacheMutable = false + + RoomServerRoomIDsCacheName = "roomserver_room_ids" + RoomServerRoomIDsCacheMaxEntries = 1024 + RoomServerRoomIDsCacheMutable = false ) type RoomServerCaches interface { @@ -34,6 +38,9 @@ type RoomServerNIDsCache interface { GetRoomServerRoomNID(roomID string) (types.RoomNID, bool) StoreRoomServerRoomNID(roomID string, nid types.RoomNID) + + GetRoomServerRoomID(roomNID types.RoomNID) (string, bool) + StoreRoomServerRoomID(roomNID types.RoomNID, roomID string) } func (c Caches) GetRoomServerStateKeyNID(stateKey string) (types.EventStateKeyNID, bool) { @@ -74,6 +81,21 @@ func (c Caches) GetRoomServerRoomNID(roomID string) (types.RoomNID, bool) { return 0, false } -func (c Caches) StoreRoomServerRoomNID(roomID string, nid types.RoomNID) { - c.RoomServerRoomNIDs.Set(roomID, nid) +func (c Caches) StoreRoomServerRoomNID(roomID string, roomNID types.RoomNID) { + c.RoomServerRoomNIDs.Set(roomID, roomNID) + c.RoomServerRoomIDs.Set(string(roomNID), roomID) +} + +func (c Caches) GetRoomServerRoomID(roomNID types.RoomNID) (string, bool) { + val, found := c.RoomServerRoomIDs.Get(string(roomNID)) + if found && val != nil { + if roomID, ok := val.(string); ok { + return roomID, true + } + } + return "", false +} + +func (c Caches) StoreRoomServerRoomID(roomNID types.RoomNID, roomID string) { + c.StoreRoomServerRoomNID(roomID, roomNID) } diff --git a/internal/caching/caches.go b/internal/caching/caches.go index 79512d153..655cc037c 100644 --- a/internal/caching/caches.go +++ b/internal/caching/caches.go @@ -9,6 +9,7 @@ type Caches struct { RoomServerStateKeyNIDs Cache // RoomServerNIDsCache RoomServerEventTypeNIDs Cache // RoomServerNIDsCache RoomServerRoomNIDs Cache // RoomServerNIDsCache + RoomServerRoomIDs Cache // RoomServerNIDsCache } // Cache is the interface that an implementation must satisfy. diff --git a/internal/caching/impl_inmemorylru.go b/internal/caching/impl_inmemorylru.go index 9187b792a..e99c18d74 100644 --- a/internal/caching/impl_inmemorylru.go +++ b/internal/caching/impl_inmemorylru.go @@ -54,12 +54,22 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) { if err != nil { return nil, err } + roomServerRoomIDs, err := NewInMemoryLRUCachePartition( + RoomServerRoomIDsCacheName, + RoomServerRoomIDsCacheMutable, + RoomServerRoomIDsCacheMaxEntries, + enablePrometheus, + ) + if err != nil { + return nil, err + } return &Caches{ RoomVersions: roomVersions, ServerKeys: serverKeys, RoomServerStateKeyNIDs: roomServerStateKeyNIDs, RoomServerEventTypeNIDs: roomServerEventTypeNIDs, RoomServerRoomNIDs: roomServerRoomNIDs, + RoomServerRoomIDs: roomServerRoomIDs, }, nil } diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go index 4e5c9c1bf..0788f6cb7 100644 --- a/roomserver/storage/shared/storage.go +++ b/roomserver/storage/shared/storage.go @@ -258,6 +258,9 @@ func (d *Database) StateEntries( func (d *Database) GetRoomVersionForRoom( ctx context.Context, roomID string, ) (gomatrixserverlib.RoomVersion, error) { + if roomVersion, ok := d.Cache.GetRoomVersion(roomID); ok { + return roomVersion, nil + } return d.RoomsTable.SelectRoomVersionForRoomID( ctx, nil, roomID, ) @@ -266,6 +269,11 @@ func (d *Database) GetRoomVersionForRoom( func (d *Database) GetRoomVersionForRoomNID( ctx context.Context, roomNID types.RoomNID, ) (gomatrixserverlib.RoomVersion, error) { + if roomID, ok := d.Cache.GetRoomServerRoomID(roomNID); ok { + if roomVersion, ok := d.Cache.GetRoomVersion(roomID); ok { + return roomVersion, nil + } + } return d.RoomsTable.SelectRoomVersionForRoomNID( ctx, roomNID, ) @@ -532,6 +540,9 @@ func (d *Database) assignRoomNID( ctx context.Context, txn *sql.Tx, roomID string, roomVersion gomatrixserverlib.RoomVersion, ) (types.RoomNID, error) { + if roomNID, ok := d.Cache.GetRoomServerRoomNID(roomID); ok { + return roomNID, nil + } // Check if we already have a numeric ID in the database. roomNID, err := d.RoomsTable.SelectRoomNID(ctx, txn, roomID) if err == sql.ErrNoRows { @@ -542,14 +553,20 @@ func (d *Database) assignRoomNID( roomNID, err = d.RoomsTable.SelectRoomNID(ctx, txn, roomID) } } + if err == nil { + d.Cache.StoreRoomServerRoomNID(roomID, roomNID) + } return roomNID, err } func (d *Database) assignEventTypeNID( ctx context.Context, txn *sql.Tx, eventType string, -) (eventTypeNID types.EventTypeNID, err error) { +) (types.EventTypeNID, error) { + if eventTypeNID, ok := d.Cache.GetRoomServerEventTypeNID(eventType); ok { + return eventTypeNID, nil + } // Check if we already have a numeric ID in the database. - eventTypeNID, err = d.EventTypesTable.SelectEventTypeNID(ctx, txn, eventType) + eventTypeNID, err := d.EventTypesTable.SelectEventTypeNID(ctx, txn, eventType) if err == sql.ErrNoRows { // We don't have a numeric ID so insert one into the database. eventTypeNID, err = d.EventTypesTable.InsertEventTypeNID(ctx, txn, eventType) @@ -558,12 +575,18 @@ func (d *Database) assignEventTypeNID( eventTypeNID, err = d.EventTypesTable.SelectEventTypeNID(ctx, txn, eventType) } } - return + if err == nil { + d.Cache.StoreRoomServerEventTypeNID(eventType, eventTypeNID) + } + return eventTypeNID, err } func (d *Database) assignStateKeyNID( ctx context.Context, txn *sql.Tx, eventStateKey string, ) (types.EventStateKeyNID, error) { + if eventStateKeyNID, ok := d.Cache.GetRoomServerStateKeyNID(eventStateKey); ok { + return eventStateKeyNID, nil + } // Check if we already have a numeric ID in the database. eventStateKeyNID, err := d.EventStateKeysTable.SelectEventStateKeyNID(ctx, txn, eventStateKey) if err == sql.ErrNoRows { @@ -574,6 +597,9 @@ func (d *Database) assignStateKeyNID( eventStateKeyNID, err = d.EventStateKeysTable.SelectEventStateKeyNID(ctx, txn, eventStateKey) } } + if err == nil { + d.Cache.StoreRoomServerStateKeyNID(eventStateKey, eventStateKeyNID) + } return eventStateKeyNID, err }