package fetchers import ( "llostre/backend/general" "llostre/backend/notes" "sync" "time" ) type CacheEntry struct { Note *notes.Note ExpiresAt time.Time } type Cache struct { posts map[string]*CacheEntry profiles map[string]*ProfileCacheEntry mu sync.RWMutex } func NewCache() *Cache { return &Cache{ posts: make(map[string]*CacheEntry), profiles: make(map[string]*ProfileCacheEntry), } } func (c *Cache) Get(uri string) (*notes.Note, bool) { c.mu.Lock() defer c.mu.Unlock() entry, exists := c.posts[uri] if !exists { return nil, false } if time.Now().After(entry.ExpiresAt) { delete(c.posts, uri) return nil, false } return entry.Note, true } func (c *Cache) Set(uri string, note *notes.Note) { c.mu.Lock() defer c.mu.Unlock() c.posts[uri] = &CacheEntry{ Note: note, ExpiresAt: time.Now().Add(15 * time.Minute), } } func (c *Cache) GetMany(uris []string) map[string]*notes.Note { c.mu.Lock() defer c.mu.Unlock() result := make(map[string]*notes.Note) now := time.Now() for _, uri := range uris { entry, exists := c.posts[uri] if !exists { continue } if now.After(entry.ExpiresAt) { delete(c.posts, uri) continue } result[uri] = entry.Note } return result } type ProfileCacheEntry struct { Profile *general.Profile ExpiresAt time.Time } func (c *Cache) GetProfile(did string) (*general.Profile, bool) { c.mu.Lock() defer c.mu.Unlock() entry, exists := c.profiles[did] if !exists { return nil, false } if time.Now().After(entry.ExpiresAt) { delete(c.profiles, did) return nil, false } return entry.Profile, true } func (c *Cache) SetProfile(did string, profile *general.Profile) { c.mu.Lock() defer c.mu.Unlock() c.profiles[did] = &ProfileCacheEntry{ Profile: profile, ExpiresAt: time.Now().Add(15 * time.Minute), } }