memory.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package cache
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // Memory is an concurrent-safe in-process cache backed by a plain map.
  7. type Memory struct {
  8. mu sync.RWMutex
  9. data map[string]*data
  10. }
  11. // data holds a single cached value together with its expiry time.
  12. type data struct {
  13. Data interface{}
  14. Expired time.Time
  15. }
  16. // NewMemory returns a ready-to-use in-memory cache.
  17. func NewMemory() *Memory {
  18. return &Memory{
  19. data: map[string]*data{},
  20. }
  21. }
  22. // Get returns the cached value for key.
  23. // Returns nil if the key does not exist or has expired.
  24. func (mem *Memory) Get(key string) interface{} {
  25. mem.mu.RLock()
  26. ret, ok := mem.data[key]
  27. expired := ok && ret.Expired.Before(time.Now())
  28. mem.mu.RUnlock()
  29. if !ok {
  30. return nil
  31. }
  32. if expired {
  33. mem.deleteExpiredKey(key)
  34. return nil
  35. }
  36. return ret.Data
  37. }
  38. // IsExist check value exists in memcache.
  39. func (mem *Memory) IsExist(key string) bool {
  40. mem.mu.RLock()
  41. ret, ok := mem.data[key]
  42. expired := ok && ret.Expired.Before(time.Now())
  43. mem.mu.RUnlock()
  44. if !ok {
  45. return false
  46. }
  47. if expired {
  48. mem.deleteExpiredKey(key)
  49. return false
  50. }
  51. return true
  52. }
  53. // Set cached value with key and expire time.
  54. func (mem *Memory) Set(key string, val interface{}, timeout time.Duration) (err error) {
  55. mem.mu.Lock()
  56. defer mem.mu.Unlock()
  57. mem.data[key] = &data{
  58. Data: val,
  59. Expired: time.Now().Add(timeout),
  60. }
  61. return nil
  62. }
  63. // Delete delete value in memcache.
  64. func (mem *Memory) Delete(key string) error {
  65. mem.mu.Lock()
  66. defer mem.mu.Unlock()
  67. delete(mem.data, key)
  68. return nil
  69. }
  70. // deleteExpiredKey deletes a key only if it has expired.
  71. // Caller must NOT hold any lock.
  72. func (mem *Memory) deleteExpiredKey(key string) {
  73. mem.mu.Lock()
  74. defer mem.mu.Unlock()
  75. if d, ok := mem.data[key]; ok && d.Expired.Before(time.Now()) {
  76. delete(mem.data, key)
  77. }
  78. }