Diffstat (limited to 'internal/router/client-cache.go')
| -rw-r--r-- | internal/router/client-cache.go | 99 |
1 files changed, 35 insertions, 64 deletions
diff --git a/internal/router/client-cache.go b/internal/router/client-cache.go index 81d7641..56cd595 100644 --- a/internal/router/client-cache.go +++ b/internal/router/client-cache.go @@ -18,14 +18,11 @@ type PageLike struct { type ClientCache struct { hashMap map[string]string - hashMapMutex sync.RWMutex - - likePageMap map[string]map[string]struct{} - pageMutexMap map[string]*sync.RWMutex - pageMutexMapMutex sync.Mutex - - salt []byte - db *sql.DB + mutexLikeMap map[string]*sync.Mutex + mutexHashMap map[string]*sync.Mutex + likePageMap map[string]map[string]struct{} + salt []byte + db *sql.DB } var CCache *ClientCache @@ -43,21 +40,20 @@ func NewClientCache(db *sql.DB, salt []byte) (*ClientCache, error) { } likePageMap := make(map[string]map[string]struct{}) - pageMutexMap := make(map[string]*sync.RWMutex) for rows.Next() { - var pageRef string - var userId []byte + pageRef := make([]byte, 32) + userId := make([]byte, 32) if err = rows.Scan(&pageRef, &userId); err != nil { tx.Rollback() return nil, fmt.Errorf("fail scanning blog_likes to fill cache: %w", err) } + pageRefString := string(pageRef) userIdString := base64.RawStdEncoding.EncodeToString(userId) - if _, ok := likePageMap[pageRef]; !ok { - likePageMap[pageRef] = make(map[string]struct{}) - pageMutexMap[pageRef] = &sync.RWMutex{} + if _, ok := likePageMap[pageRefString]; !ok { + likePageMap[pageRefString] = make(map[string]struct{}) } - likePageMap[pageRef][userIdString] = struct{}{} + likePageMap[pageRefString][userIdString] = struct{}{} } if err = tx.Commit(); err != nil { @@ -66,8 +62,9 @@ func NewClientCache(db *sql.DB, salt []byte) (*ClientCache, error) { return &ClientCache{ hashMap: make(map[string]string), + mutexLikeMap: make(map[string]*sync.Mutex), + mutexHashMap: make(map[string]*sync.Mutex), likePageMap: likePageMap, - pageMutexMap: pageMutexMap, salt: salt, db: db, }, nil @@ -79,20 +76,17 @@ func (c *ClientCache) Close() error { return fmt.Errorf("fail to init transaction with db to dump cache: %w", err) } - if _, err = tx.Exec("delete from blog_likes;"); err != nil { - tx.Rollback() - return fmt.Errorf("fail to truncate table blog_likes: %w", err) - } - userIdBytes := make(map[string][]byte) sqlStatement := fmt.Sprintf(` INSERT OR IGNORE INTO blog_likes (page_ref, user_id) VALUES %s(?, ?); `, strings.Repeat("(?, ?), ", 99)) - sqlStatementVars := make([]any, 0, 200) + sqlStatementVars := make([]interface{}, 0, 200) for pageRef, userSet := range c.likePageMap { + pageRefBytes := []byte(pageRef) + for userId := range userSet { if _, ok := userIdBytes[userId]; !ok { userIdBytes[userId], err = base64.RawStdEncoding.DecodeString(userId) @@ -102,7 +96,7 @@ func (c *ClientCache) Close() error { } } - sqlStatementVars = append(sqlStatementVars, any(pageRef), any(userIdBytes[userId])) + sqlStatementVars = append(sqlStatementVars, interface{}(pageRefBytes), interface{}(userIdBytes[userId])) if len(sqlStatementVars) < 200 { continue } @@ -111,7 +105,7 @@ func (c *ClientCache) Close() error { slog.Warn("couldn't insert blog like pairs into db", slog.String("error", err.Error())) } - sqlStatementVars = make([]any, 0, 200) + sqlStatementVars = make([]interface{}, 0, 200) } } @@ -130,16 +124,16 @@ func (c *ClientCache) Close() error { } func (c *ClientCache) GetHash(id string) string { - c.hashMapMutex.RLock() if val, ok := c.hashMap[id]; ok { - c.hashMapMutex.RUnlock() slog.Debug("gave an old hash", slog.String("hash", val)) return val } - c.hashMapMutex.RUnlock() - c.hashMapMutex.Lock() - defer c.hashMapMutex.Unlock() + if _, ok := c.mutexHashMap[id]; !ok { + c.mutexHashMap[id] = &sync.Mutex{} + } + c.mutexHashMap[id].Lock() + defer c.mutexHashMap[id].Unlock() if val, ok := c.hashMap[id]; ok { slog.Debug("gave a newly generated hash", slog.String("hash", val)) @@ -151,25 +145,7 @@ func (c *ClientCache) GetHash(id string) string { return c.hashMap[id] } -func (c *ClientCache) getPageMutex(page string) *sync.RWMutex { - c.pageMutexMapMutex.Lock() - defer c.pageMutexMapMutex.Unlock() - - if mutex, ok := c.pageMutexMap[page]; ok { - return mutex - } - - c.pageMutexMap[page] = &sync.RWMutex{} - return c.pageMutexMap[page] -} - func (c *ClientCache) GetLikeStatus(id string, page string) bool { - page = strings.Clone(page) - - mutex := c.getPageMutex(page) - mutex.RLock() - defer mutex.RUnlock() - if _, ok := c.likePageMap[page]; !ok { return false } @@ -178,12 +154,6 @@ func (c *ClientCache) GetLikeStatus(id string, page string) bool { } func (c *ClientCache) GetLikeCount(page string) int { - page = strings.Clone(page) - - mutex := c.getPageMutex(page) - mutex.RLock() - defer mutex.RUnlock() - if userSet, ok := c.likePageMap[page]; ok { return len(userSet) } @@ -191,12 +161,13 @@ func (c *ClientCache) GetLikeCount(page string) int { } func (c *ClientCache) LikeOn(id string, page string) (alreadyLiked bool) { - page = strings.Clone(page) - hash := c.GetHash(id) + if _, ok := c.mutexLikeMap[id]; !ok { + c.mutexLikeMap[id] = &sync.Mutex{} + } + c.mutexLikeMap[id].Lock() + defer c.mutexLikeMap[id].Unlock() - mutex := c.getPageMutex(page) - mutex.Lock() - defer mutex.Unlock() + hash := c.GetHash(id) if userSet, ok := c.likePageMap[page]; ok { _, alreadyLiked = userSet[hash] @@ -210,16 +181,16 @@ func (c *ClientCache) LikeOn(id string, page string) (alreadyLiked bool) { } func (c *ClientCache) LikeOff(id string, page string) (alreadyUnliked bool) { - page = strings.Clone(page) - hash := c.GetHash(id) - - mutex := c.getPageMutex(page) - mutex.Lock() - defer mutex.Unlock() + if _, ok := c.mutexLikeMap[id]; !ok { + c.mutexLikeMap[id] = &sync.Mutex{} + } + c.mutexLikeMap[id].Lock() + defer c.mutexLikeMap[id].Unlock() if _, ok := c.likePageMap[page]; !ok { return true } + hash := c.GetHash(id) if _, ok := c.likePageMap[page][hash]; !ok { return true } |