Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions config/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,13 @@ type CachedAttachment struct {

// CachedEmailBody stores the body and attachment metadata for a single email.
type CachedEmailBody struct {
UID uint32 `json:"uid"`
AccountID string `json:"account_id"`
Body string `json:"body"`
Attachments []CachedAttachment `json:"attachments,omitempty"`
CachedAt time.Time `json:"cached_at"`
UID uint32 `json:"uid"`
AccountID string `json:"account_id"`
Body string `json:"body"`
Attachments []CachedAttachment `json:"attachments,omitempty"`
CachedAt time.Time `json:"cached_at"`
LastAccessedAt time.Time `json:"last_accessed_at"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see, this is never updated. Should be updated on GetCachedEmailBody.

SizeBytes int `json:"size_bytes"`
}

// EmailBodyCache stores cached email bodies for a folder.
Expand Down Expand Up @@ -503,14 +505,36 @@ func GetCachedEmailBody(folderName string, uid uint32, accountID string) *Cached
return nil
}

func calculateTotalCacheSize(cache *EmailBodyCache) int {
total := 0
for _, b := range cache.Bodies {
total += b.SizeBytes
}
return total
}

func evict(cache *EmailBodyCache, newSize int, threshold int) {
sort.Slice(cache.Bodies, func(i, j int) bool {
return cache.Bodies[i].LastAccessedAt.Before(cache.Bodies[j].LastAccessedAt)
})

for len(cache.Bodies) > 0 && calculateTotalCacheSize(cache)+newSize > threshold {
cache.Bodies = cache.Bodies[1:]
}
}

// SaveEmailBody saves or updates a cached email body for a folder.
func SaveEmailBody(folderName string, body CachedEmailBody) error {
cache, err := LoadEmailBodyCache(folderName)
if err != nil {
cache = &EmailBodyCache{FolderName: folderName}
}

const threshold = 500 * 1024 * 1024 // 500MB

body.CachedAt = time.Now()
body.LastAccessedAt = time.Now()
body.SizeBytes = len(body.Body)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does not count CachedAttachments, while it should. Will lead to a much larger cache, than set in config.


// Replace existing or append
found := false
Expand All @@ -522,6 +546,11 @@ func SaveEmailBody(folderName string, body CachedEmailBody) error {
}
}
if !found {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The least of my concerns, but also worth noting, that, if the email is changed (found=true still) the cache is not going to be evicted


if calculateTotalCacheSize(cache)+body.SizeBytes > threshold {
evict(cache, body.SizeBytes, threshold)
}

cache.Bodies = append(cache.Bodies, body)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If one new email is more than the threshold, evict will drain the cache and still append.

}

Expand Down
Loading