github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/cache/internal.go (about) 1 package cache 2 3 import ( 4 "context" 5 "sync" 6 "sync/atomic" 7 "time" 8 "unsafe" 9 ) 10 11 var ( 12 cache = make(map[string]*internalCacheT) 13 disabled = true // avoid the cache for unit tests 14 ) 15 16 type internalCacheT struct { 17 mutex sync.Mutex 18 cache map[string]*cacheItemT 19 } 20 21 type cacheItemT struct { 22 value *[]byte 23 ttl time.Time 24 } 25 26 func (lc *internalCacheT) Read(key string, ptr unsafe.Pointer) bool { 27 if disabled { 28 return false 29 } 30 31 lc.mutex.Lock() 32 v, ok := lc.cache[key] 33 lc.mutex.Unlock() 34 35 if !ok { 36 return false 37 } 38 39 if v.ttl.After(time.Now()) { 40 return false 41 } 42 43 atomic.StorePointer(&ptr, unsafe.Pointer(v.value)) 44 return true 45 } 46 47 type internalDumpT struct { 48 Key string 49 Value string 50 TTL string 51 } 52 53 func (lc *internalCacheT) Dump(ctx context.Context) interface{} { 54 if disabled { 55 return nil 56 } 57 58 var s []internalDumpT 59 60 lc.mutex.Lock() 61 62 for key, item := range lc.cache { 63 select { 64 case <-ctx.Done(): 65 lc.mutex.Unlock() 66 return nil 67 68 default: 69 if item.ttl.After(time.Now()) { 70 s = append(s, internalDumpT{ 71 Key: key, 72 Value: string(*item.value), 73 TTL: item.ttl.Format(time.UnixDate), 74 }) 75 } 76 } 77 } 78 79 lc.mutex.Unlock() 80 81 return s 82 } 83 84 func (lc *internalCacheT) Write(key string, value *[]byte, ttl time.Time) { 85 if disabled { 86 return 87 } 88 89 lc.mutex.Lock() 90 lc.cache[key] = &cacheItemT{value, ttl} 91 lc.mutex.Unlock() 92 } 93 94 func (lc *internalCacheT) Trim(ctx context.Context) []string { 95 if disabled { 96 return nil 97 } 98 99 var s []string 100 101 lc.mutex.Lock() 102 103 for key, item := range lc.cache { 104 select { 105 case <-ctx.Done(): 106 lc.mutex.Unlock() 107 return s 108 109 default: 110 if item.ttl.Before(time.Now()) { 111 delete(lc.cache, key) 112 s = append(s, key) 113 } 114 } 115 } 116 117 lc.mutex.Unlock() 118 119 return s 120 } 121 122 func (lc *internalCacheT) Flush(ctx context.Context) []string { 123 if disabled { 124 return nil 125 } 126 127 var s []string 128 129 lc.mutex.Lock() 130 131 for key := range lc.cache { 132 select { 133 case <-ctx.Done(): 134 lc.mutex.Unlock() 135 return s 136 137 default: 138 delete(lc.cache, key) 139 s = append(s, key) 140 } 141 } 142 143 lc.mutex.Unlock() 144 145 return s 146 }