diff options
Diffstat (limited to 'internal/cache/status.go')
-rw-r--r-- | internal/cache/status.go | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/internal/cache/status.go b/internal/cache/status.go index 895a5692c..028abc8f7 100644 --- a/internal/cache/status.go +++ b/internal/cache/status.go @@ -37,7 +37,7 @@ func NewStatusCache() *StatusCache { return &c } -// GetByID attempts to fetch a status from the cache by its ID +// GetByID attempts to fetch a status from the cache by its ID, you will receive a copy for thread-safety func (c *StatusCache) GetByID(id string) (*gtsmodel.Status, bool) { c.mutex.Lock() status, ok := c.getByID(id) @@ -45,7 +45,7 @@ func (c *StatusCache) GetByID(id string) (*gtsmodel.Status, bool) { return status, ok } -// GetByURL attempts to fetch a status from the cache by its URL +// GetByURL attempts to fetch a status from the cache by its URL, you will receive a copy for thread-safety func (c *StatusCache) GetByURL(url string) (*gtsmodel.Status, bool) { // Perform safe ID lookup c.mutex.Lock() @@ -63,7 +63,7 @@ func (c *StatusCache) GetByURL(url string) (*gtsmodel.Status, bool) { return status, ok } -// GetByURI attempts to fetch a status from the cache by its URI +// GetByURI attempts to fetch a status from the cache by its URI, you will receive a copy for thread-safety func (c *StatusCache) GetByURI(uri string) (*gtsmodel.Status, bool) { // Perform safe ID lookup c.mutex.Lock() @@ -81,26 +81,72 @@ func (c *StatusCache) GetByURI(uri string) (*gtsmodel.Status, bool) { return status, ok } -// getByID performs an unsafe (no mutex locks) lookup of status by ID +// getByID performs an unsafe (no mutex locks) lookup of status by ID, returning a copy of status in cache func (c *StatusCache) getByID(id string) (*gtsmodel.Status, bool) { v, ok := c.cache.Get(id) if !ok { return nil, false } - return v.(*gtsmodel.Status), true + return copyStatus(v.(*gtsmodel.Status)), true } -// Put places a status in the cache +// Put places a status in the cache, ensuring that the object place is a copy for thread-safety func (c *StatusCache) Put(status *gtsmodel.Status) { - if status == nil || status.ID == "" || - status.URL == "" || - status.URI == "" { + if status == nil || status.ID == "" { panic("invalid status") } c.mutex.Lock() - c.cache.Set(status.ID, status) - c.urls[status.URL] = status.ID - c.uris[status.URI] = status.ID + c.cache.Set(status.ID, copyStatus(status)) + if status.URL != "" { + c.urls[status.URL] = status.ID + } + if status.URI != "" { + c.uris[status.URI] = status.ID + } c.mutex.Unlock() } + +// copyStatus performs a surface-level copy of status, only keeping attached IDs intact, not the objects. +// due to all the data being copied being 99% primitive types or strings (which are immutable and passed by ptr) +// this should be a relatively cheap process +func copyStatus(status *gtsmodel.Status) *gtsmodel.Status { + return >smodel.Status{ + ID: status.ID, + URI: status.URI, + URL: status.URL, + Content: status.Content, + AttachmentIDs: status.AttachmentIDs, + Attachments: nil, + TagIDs: status.TagIDs, + Tags: nil, + MentionIDs: status.MentionIDs, + Mentions: nil, + EmojiIDs: status.EmojiIDs, + Emojis: nil, + CreatedAt: status.CreatedAt, + UpdatedAt: status.UpdatedAt, + Local: status.Local, + AccountID: status.AccountID, + Account: nil, + AccountURI: status.AccountURI, + InReplyToID: status.InReplyToID, + InReplyTo: nil, + InReplyToURI: status.InReplyToURI, + InReplyToAccountID: status.InReplyToAccountID, + InReplyToAccount: nil, + BoostOfID: status.BoostOfID, + BoostOf: nil, + BoostOfAccountID: status.BoostOfAccountID, + BoostOfAccount: nil, + ContentWarning: status.ContentWarning, + Visibility: status.Visibility, + Sensitive: status.Sensitive, + Language: status.Language, + CreatedWithApplicationID: status.CreatedWithApplicationID, + VisibilityAdvanced: status.VisibilityAdvanced, + ActivityStreamsType: status.ActivityStreamsType, + Text: status.Text, + Pinned: status.Pinned, + } +} |