Commit 92e3da8e by feidy

Add Auto Gc Map

parent 23c65280
package utils
import (
"sync"
"time"
)
const (
// NeverDie means value.alive() returns true forever.
NeverDie = 0
)
type value struct {
data interface{}
ttl int64 //time.Second
ctime time.Time
}
func newValue(data interface{}, ttl int64) *value {
return &value{
data: data,
ttl: ttl,
ctime: time.Now(),
}
}
func (v *value) alive() bool {
return v.ttl == NeverDie || time.Now().Before(v.ctime.Add(time.Duration(v.ttl)*time.Second))
}
type AutoGcMap struct {
data map[string]*value
lock *sync.RWMutex
}
func NewAutoGcMap() *AutoGcMap {
return &AutoGcMap{
data: make(map[string]*value),
lock: &sync.RWMutex{},
}
}
func (my *AutoGcMap) set(key string, data interface{}, ttl int64) {
my.lock.Lock()
defer my.lock.Unlock()
my.data[key] = newValue(data, ttl)
}
func (my *AutoGcMap) get(key string) (interface{}, bool) {
my.lock.Lock()
defer my.lock.Unlock()
if value, ok := my.data[key]; ok && value.alive() {
return value.data, true
}
return nil, false
}
func (my *AutoGcMap) Gc() {
my.lock.Lock()
defer my.lock.Unlock()
for key, value := range my.data {
if !value.alive() {
delete(my.data, key)
}
}
}
func (my *AutoGcMap) AutoGc(duration time.Duration) {
go func() {
ticker := time.NewTicker(duration)
for {
<-ticker.C
my.Gc()
}
}()
}
package utils
import (
"testing"
"time"
"github.com/go-playground/assert/v2"
)
func TestAutoGc(t *testing.T) {
m := NewAutoGcMap()
m.AutoGc(3)
m.set("a", "b", 10)
time.Sleep(10 * time.Second)
_, b := m.get("a")
assert.Equal(t, b, false)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment