package fetchers import ( "llostre/backend/notes" "sync" "time" ) type CacheEntry struct { Note *notes.Note ExpiresAt time.Time } type Cache struct { posts map[string]*CacheEntry profiles map[string]*AuthorCacheEntry mu sync.RWMutex } func NewCache() *Cache { return &Cache{ posts: make(map[string]*CacheEntry), profiles: make(map[string]*AuthorCacheEntry), } } 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 AuthorCacheEntry struct { Author *notes.Author ExpiresAt time.Time } func (c *Cache) GetProfile(did string) (*notes.Author, 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.Author, true } func (c *Cache) SetAuthor(did string, author *notes.Author) { c.mu.Lock() defer c.mu.Unlock() c.profiles[did] = &AuthorCacheEntry{ Author: author, ExpiresAt: time.Now().Add(15 * time.Minute), } }