From 9d970d2fc7502a03731d673b7ec36f51bc36842e Mon Sep 17 00:00:00 2001 From: qydysky Date: Fri, 26 May 2023 01:33:26 +0800 Subject: [PATCH] add --- sync/Map.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ sync/Map_test.go | 14 ++++++++++++++ web/Web.go | 13 +++++++++++++ 3 files changed, 77 insertions(+) diff --git a/sync/Map.go b/sync/Map.go index 12b5d31..67c2ebb 100644 --- a/sync/Map.go +++ b/sync/Map.go @@ -3,6 +3,7 @@ package part import ( "sync" "sync/atomic" + "time" ) type Map struct { @@ -61,3 +62,52 @@ func Copy[T comparable, S any](s map[T]S) map[T]S { } return t } + +type MapExceeded[K, V any] struct { + m Map +} + +type mapExceededItem[V any] struct { + data *V + exceeded time.Time +} + +func (t *MapExceeded[K, V]) Store(k K, v V, dur time.Duration) { + t.m.Store(k, mapExceededItem[V]{ + data: &v, + exceeded: time.Now().Add(dur), + }) +} + +func (t *MapExceeded[K, V]) Load(k K) (*V, bool) { + if v, ok := t.m.Load(k); ok { + if v.(mapExceededItem[V]).exceeded.After(time.Now()) { + return v.(mapExceededItem[V]).data, true + } + t.Delete(k) + } + return nil, false +} + +func (t *MapExceeded[K, V]) Range(f func(key K, value *V) bool) { + t.m.Range(func(key, value any) bool { + if value.(mapExceededItem[V]).exceeded.After(time.Now()) { + return f(key.(K), value.(*V)) + } + t.Delete(key.(K)) + return true + }) +} + +func (t *MapExceeded[K, V]) GC(dur ...time.Duration) { + t.m.Range(func(key, value any) bool { + if value.(mapExceededItem[V]).exceeded.Before(time.Now()) { + t.Delete(key.(K)) + } + return true + }) +} + +func (t *MapExceeded[K, V]) Delete(k K) { + t.m.Delete(k) +} diff --git a/sync/Map_test.go b/sync/Map_test.go index a8d468f..609d2c9 100644 --- a/sync/Map_test.go +++ b/sync/Map_test.go @@ -1,8 +1,10 @@ package part import ( + "bytes" "sync" "testing" + "time" ) type tmp struct { @@ -331,3 +333,15 @@ func Benchmark_syncMap_Range(b *testing.B) { return true }) } + +func TestMapExceeded1(t *testing.T) { + var m MapExceeded[string, []byte] + m.Store("1", []byte("1"), time.Second) + if b, ok := m.Load("1"); !ok || 0 != bytes.Compare(*b, []byte("1")) { + t.Fatal(ok, b) + } + time.Sleep(time.Second * 2) + if b, ok := m.Load("1"); ok || b != nil { + t.Fatal() + } +} diff --git a/web/Web.go b/web/Web.go index 014da5f..ec17ac8 100644 --- a/web/Web.go +++ b/web/Web.go @@ -9,6 +9,7 @@ import ( "sync" "time" + psync "github.com/qydysky/part/sync" sys "github.com/qydysky/part/sys" ) @@ -222,6 +223,18 @@ func (t *CountLimits) AddCount(r *http.Request) (isOverflow bool) { return } +type Cache struct { + g psync.MapExceeded[string, []byte] +} + +func (t *Cache) IsCache(key string) (res *[]byte, isCache bool) { + return t.g.Load(key) +} + +func (t *Cache) Store(key string, aliveDur time.Duration, data []byte) { + t.g.Store(key, data, aliveDur) +} + func Easy_boot() *Web { s := New(&http.Server{ Addr: "127.0.0.1:" + strconv.Itoa(sys.Sys().GetFreePort()), -- 2.39.2