mirror of
https://github.com/samuelncui/yatm.git
synced 2026-01-05 13:05:42 +00:00
feat: add rollback and virtual list
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package tools
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func Cache[K comparable, V any](f func(in K) V) func(in K) V {
|
||||
cache := new(sync.Map)
|
||||
@@ -15,3 +18,66 @@ func Cache[K comparable, V any](f func(in K) V) func(in K) V {
|
||||
return out
|
||||
}
|
||||
}
|
||||
|
||||
func ThreadUnsafeCache[K comparable, V any](f func(in K) V) func(in K) V {
|
||||
cache := make(map[K]V, 32)
|
||||
return func(in K) V {
|
||||
cached, has := cache[in]
|
||||
if has {
|
||||
return cached
|
||||
}
|
||||
|
||||
out := f(in)
|
||||
cache[in] = out
|
||||
return out
|
||||
}
|
||||
}
|
||||
|
||||
type CacheOnce[K comparable, V any] struct {
|
||||
cached sync.Map
|
||||
getter func(context.Context, K) (V, error)
|
||||
}
|
||||
|
||||
type cacheOnceItem[V any] struct {
|
||||
once sync.Once
|
||||
value V
|
||||
}
|
||||
|
||||
func NewCacheOnce[K comparable, V any](getter func(context.Context, K) (V, error)) *CacheOnce[K, V] {
|
||||
return &CacheOnce[K, V]{getter: getter}
|
||||
}
|
||||
|
||||
func (c *CacheOnce[K, V]) Get(ctx context.Context, req K) (V, error) {
|
||||
if v, have := c.cached.Load(req); have {
|
||||
item, ok := v.(*cacheOnceItem[V])
|
||||
if ok {
|
||||
return c.get(ctx, item, req)
|
||||
}
|
||||
}
|
||||
|
||||
v, _ := c.cached.LoadOrStore(req, &cacheOnceItem[V]{})
|
||||
return c.get(ctx, v.(*cacheOnceItem[V]), req)
|
||||
}
|
||||
|
||||
func (c *CacheOnce[K, V]) Remove(req K) {
|
||||
c.cached.Delete(req)
|
||||
}
|
||||
|
||||
func (c *CacheOnce[K, V]) get(ctx context.Context, item *cacheOnceItem[V], key K) (V, error) {
|
||||
var err error
|
||||
item.once.Do(func() {
|
||||
v, e := c.getter(ctx, key)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
item.value = v
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
var v V
|
||||
return v, err
|
||||
}
|
||||
|
||||
return item.value, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user