mirror of
https://github.com/zhaojh329/rttys.git
synced 2026-02-27 09:53:21 +08:00
bfefcdb0bd
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
112 lines
1.7 KiB
Go
112 lines
1.7 KiB
Go
package cache
|
|
|
|
import (
|
|
"runtime"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Item struct {
|
|
value any
|
|
expiration int64
|
|
}
|
|
|
|
type Cache struct {
|
|
items sync.Map
|
|
defaultExpiration time.Duration
|
|
gcInterval time.Duration
|
|
stop chan struct{}
|
|
}
|
|
|
|
// Delete all expired items from the cache.
|
|
func (c *Cache) DeleteExpired() {
|
|
now := time.Now().UnixNano()
|
|
|
|
c.items.Range(func(key, value any) bool {
|
|
if value := value.(*Item); value.expiration > 0 && now > value.expiration {
|
|
c.items.Delete(key)
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
func (c *Cache) gcLoop() {
|
|
ticker := time.NewTicker(c.gcInterval)
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
c.DeleteExpired()
|
|
case <-c.stop:
|
|
ticker.Stop()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func New(defaultExpiration, gcInterval time.Duration) *Cache {
|
|
c := &Cache{
|
|
defaultExpiration: defaultExpiration,
|
|
gcInterval: gcInterval,
|
|
stop: make(chan struct{}),
|
|
}
|
|
|
|
go c.gcLoop()
|
|
|
|
runtime.SetFinalizer(c, func(c *Cache) {
|
|
c.stop <- struct{}{}
|
|
})
|
|
return c
|
|
}
|
|
|
|
func (c *Cache) Active(key any, d time.Duration) {
|
|
v, ok := c.items.Load(key)
|
|
if ok {
|
|
v := v.(*Item)
|
|
|
|
var e int64
|
|
|
|
if d == 0 {
|
|
d = c.defaultExpiration
|
|
}
|
|
|
|
if d > 0 {
|
|
e = time.Now().Add(d).UnixNano()
|
|
}
|
|
|
|
v.expiration = e
|
|
}
|
|
}
|
|
|
|
func (c *Cache) Set(key, value any, d time.Duration) {
|
|
var e int64
|
|
|
|
if d == 0 {
|
|
d = c.defaultExpiration
|
|
}
|
|
|
|
if d > 0 {
|
|
e = time.Now().Add(d).UnixNano()
|
|
}
|
|
|
|
c.items.Store(key, &Item{value, e})
|
|
}
|
|
|
|
func (c *Cache) Get(key any) (any, bool) {
|
|
v, ok := c.items.Load(key)
|
|
if ok {
|
|
v := v.(*Item)
|
|
return v.value, true
|
|
}
|
|
|
|
return nil, false
|
|
}
|
|
|
|
func (c *Cache) Del(key any) {
|
|
c.items.Delete(key)
|
|
}
|
|
|
|
func (c *Cache) Have(key string) bool {
|
|
_, ok := c.items.Load(key)
|
|
return ok
|
|
}
|