1
0

cache.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package ttl_memory_cache
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. type Cache struct {
  7. expiration *time.Duration
  8. mu sync.RWMutex
  9. items map[string]Item
  10. }
  11. type Item struct {
  12. Value interface{}
  13. ExpiredAt *time.Time
  14. }
  15. func NewCache(c Config) *Cache {
  16. cache := Cache{
  17. items: make(map[string]Item),
  18. expiration: c.expiration,
  19. }
  20. return &cache
  21. }
  22. func (c *Cache) Set(key string, value interface{}, expiration *time.Duration) {
  23. item := Item{
  24. Value: value,
  25. }
  26. if expiration != nil {
  27. expiredAt := time.Now().Add(*expiration)
  28. item.ExpiredAt = &expiredAt
  29. } else if c.expiration != nil {
  30. expiredAt := time.Now().Add(*c.expiration)
  31. item.ExpiredAt = &expiredAt
  32. }
  33. c.mu.Lock()
  34. defer c.mu.Unlock()
  35. c.items[key] = item
  36. }
  37. func (c *Cache) Get(key string) (interface{}, bool) {
  38. c.mu.RLock()
  39. item, found := c.items[key]
  40. if !found {
  41. c.mu.RUnlock()
  42. return nil, false
  43. }
  44. if item.ExpiredAt == nil {
  45. c.mu.RUnlock()
  46. return item.Value, true
  47. }
  48. if time.Now().Before(*item.ExpiredAt) {
  49. c.mu.RUnlock()
  50. return item.Value, true
  51. }
  52. c.mu.RUnlock() // defer not used due to deadlocks
  53. c.Delete(key)
  54. return nil, false
  55. }
  56. func (c *Cache) Delete(key string) {
  57. c.mu.Lock()
  58. defer c.mu.Unlock()
  59. if _, found := c.items[key]; found {
  60. delete(c.items, key)
  61. }
  62. }
  63. func (c *Cache) Clear() {
  64. c.mu.Lock()
  65. defer c.mu.Unlock()
  66. c.items = make(map[string]Item)
  67. }