feat: add rollback and virtual list

This commit is contained in:
Samuel N Cui
2023-10-12 22:54:07 +08:00
parent 7a2fb83d36
commit 59f626cef5
44 changed files with 3170 additions and 2560 deletions

View File

@@ -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
}