aboutsummaryrefslogtreecommitdiff
path: root/internal/caching
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2022-04-19 10:46:45 +0200
committerGitHub <noreply@github.com>2022-04-19 09:46:45 +0100
commit57e3622b85fd4d80d9826404135f09e91ed47973 (patch)
treeecedc835dfd4b6eb21ff3b028df8f43cfb65a01f /internal/caching
parent3ddbffd59ece5f74d951d6209882d9d954db4bc3 (diff)
Implement lazy loading on `/sync` (#2346)
* Initial work on lazyloading * Partially implement lazy loading on /sync * Rename methods * Make missing tests pass * Preallocate slice, even if it will end up with fewer values * Let the cache handle the user mapping * Linter * Cap cache growth
Diffstat (limited to 'internal/caching')
-rw-r--r--internal/caching/cache_lazy_load_members.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/caching/cache_lazy_load_members.go b/internal/caching/cache_lazy_load_members.go
new file mode 100644
index 00000000..71a31762
--- /dev/null
+++ b/internal/caching/cache_lazy_load_members.go
@@ -0,0 +1,86 @@
+package caching
+
+import (
+ "fmt"
+ "time"
+
+ userapi "github.com/matrix-org/dendrite/userapi/api"
+)
+
+const (
+ LazyLoadCacheName = "lazy_load_members"
+ LazyLoadCacheMaxEntries = 128
+ LazyLoadCacheMaxUserEntries = 128
+ LazyLoadCacheMutable = true
+ LazyLoadCacheMaxAge = time.Minute * 30
+)
+
+type LazyLoadCache struct {
+ // InMemoryLRUCachePartition containing other InMemoryLRUCachePartitions
+ // with the actual cached members
+ userCaches *InMemoryLRUCachePartition
+}
+
+// NewLazyLoadCache creates a new LazyLoadCache.
+func NewLazyLoadCache() (*LazyLoadCache, error) {
+ cache, err := NewInMemoryLRUCachePartition(
+ LazyLoadCacheName,
+ LazyLoadCacheMutable,
+ LazyLoadCacheMaxEntries,
+ LazyLoadCacheMaxAge,
+ true,
+ )
+ if err != nil {
+ return nil, err
+ }
+ go cacheCleaner(cache)
+ return &LazyLoadCache{
+ userCaches: cache,
+ }, nil
+}
+
+func (c *LazyLoadCache) lazyLoadCacheForUser(device *userapi.Device) (*InMemoryLRUCachePartition, error) {
+ cacheName := fmt.Sprintf("%s/%s", device.UserID, device.ID)
+ userCache, ok := c.userCaches.Get(cacheName)
+ if ok && userCache != nil {
+ if cache, ok := userCache.(*InMemoryLRUCachePartition); ok {
+ return cache, nil
+ }
+ }
+ cache, err := NewInMemoryLRUCachePartition(
+ LazyLoadCacheName,
+ LazyLoadCacheMutable,
+ LazyLoadCacheMaxUserEntries,
+ LazyLoadCacheMaxAge,
+ false,
+ )
+ if err != nil {
+ return nil, err
+ }
+ c.userCaches.Set(cacheName, cache)
+ go cacheCleaner(cache)
+ return cache, nil
+}
+
+func (c *LazyLoadCache) StoreLazyLoadedUser(device *userapi.Device, roomID, userID, eventID string) {
+ cache, err := c.lazyLoadCacheForUser(device)
+ if err != nil {
+ return
+ }
+ cacheKey := fmt.Sprintf("%s/%s/%s/%s", device.UserID, device.ID, roomID, userID)
+ cache.Set(cacheKey, eventID)
+}
+
+func (c *LazyLoadCache) IsLazyLoadedUserCached(device *userapi.Device, roomID, userID string) (string, bool) {
+ cache, err := c.lazyLoadCacheForUser(device)
+ if err != nil {
+ return "", false
+ }
+
+ cacheKey := fmt.Sprintf("%s/%s/%s/%s", device.UserID, device.ID, roomID, userID)
+ val, ok := cache.Get(cacheKey)
+ if !ok {
+ return "", ok
+ }
+ return val.(string), ok
+}