cache.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package store
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/gob"
  6. "fmt"
  7. "github.com/VictoriaMetrics/fastcache"
  8. "github.com/usememos/memos/api"
  9. )
  10. var (
  11. // 64 MiB.
  12. cacheSize = 1024 * 1024 * 64
  13. _ api.CacheService = (*CacheService)(nil)
  14. )
  15. // CacheService implements a cache.
  16. type CacheService struct {
  17. cache *fastcache.Cache
  18. }
  19. // NewCacheService creates a cache service.
  20. func NewCacheService() *CacheService {
  21. return &CacheService{
  22. cache: fastcache.New(cacheSize),
  23. }
  24. }
  25. // FindCache finds the value in cache.
  26. func (s *CacheService) FindCache(namespace api.CacheNamespace, id int, entry interface{}) (bool, error) {
  27. buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
  28. binary.LittleEndian.PutUint64(buf1, uint64(id))
  29. buf2, has := s.cache.HasGet(nil, append([]byte(namespace), buf1...))
  30. if has {
  31. dec := gob.NewDecoder(bytes.NewReader(buf2))
  32. if err := dec.Decode(entry); err != nil {
  33. return false, fmt.Errorf("failed to decode entry for cache namespace: %s, error: %w", namespace, err)
  34. }
  35. return true, nil
  36. }
  37. return false, nil
  38. }
  39. // UpsertCache upserts the value to cache.
  40. func (s *CacheService) UpsertCache(namespace api.CacheNamespace, id int, entry interface{}) error {
  41. buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
  42. binary.LittleEndian.PutUint64(buf1, uint64(id))
  43. var buf2 bytes.Buffer
  44. enc := gob.NewEncoder(&buf2)
  45. if err := enc.Encode(entry); err != nil {
  46. return fmt.Errorf("failed to encode entry for cache namespace: %s, error: %w", namespace, err)
  47. }
  48. s.cache.Set(append([]byte(namespace), buf1...), buf2.Bytes())
  49. return nil
  50. }
  51. // DeleteCache deletes the cache.
  52. func (s *CacheService) DeleteCache(namespace api.CacheNamespace, id int) {
  53. buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
  54. binary.LittleEndian.PutUint64(buf1, uint64(id))
  55. _, has := s.cache.HasGet(nil, append([]byte(namespace), buf1...))
  56. if has {
  57. s.cache.Del(append([]byte(namespace), buf1...))
  58. }
  59. }