]> 127.0.0.1 Git - part/.git/commitdiff
add
authorqydysky <qydysky@foxmail.com>
Thu, 25 May 2023 17:33:26 +0000 (01:33 +0800)
committerqydysky <qydysky@foxmail.com>
Thu, 25 May 2023 17:33:26 +0000 (01:33 +0800)
sync/Map.go
sync/Map_test.go
web/Web.go

index 12b5d313729040c14860ed8d03dc5638f63b373c..67c2ebb1e13c88113dd76a2657b779ecd510a4b3 100644 (file)
@@ -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)
+}
index a8d468fd3195f0891adb21f0ff7349217ddd03c8..609d2c91fa5cb380baeb1a31fbc0677e4bb6903e 100644 (file)
@@ -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()
+       }
+}
index 014da5f6d9af2bb9f8bcf1ab53c6718fcc62f632..ec17ac883d836ac951e9ca2aec3417aed3309783 100644 (file)
@@ -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()),