package render import ( "os" "sync" "time" ) type cacheEntry struct { html []byte modTime time.Time } type Cache struct { mu sync.RWMutex items map[string]*cacheEntry } func NewCache() *Cache { return &Cache{items: make(map[string]*cacheEntry)} } func (c *Cache) Get(filePath string) ([]byte, error) { info, err := os.Stat(filePath) if err != nil { return nil, err } c.mu.RLock() entry, ok := c.items[filePath] c.mu.RUnlock() if ok && entry.modTime.Equal(info.ModTime()) { return entry.html, nil } src, err := os.ReadFile(filePath) if err != nil { return nil, err } rendered, err := Markdown(src) if err != nil { return nil, err } c.mu.Lock() c.items[filePath] = &cacheEntry{html: rendered, modTime: info.ModTime()} c.mu.Unlock() return rendered, nil } func (c *Cache) Invalidate(filePath string) { c.mu.Lock() delete(c.items, filePath) c.mu.Unlock() } func (c *Cache) Clear() { c.mu.Lock() c.items = make(map[string]*cacheEntry) c.mu.Unlock() }