1 Star 0 Fork 0

h79/goutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cache.go 3.88 KB
一键复制 编辑 原始数据 按行查看 历史
huqiuyun 提交于 2024-08-25 23:49 . scheduler job for system quit
package cache
import (
"sync"
)
type Key interface {
~int | ~int16 | ~int32 | ~int64 | ~uint32 | uint16 | ~uint | ~string
}
type Child[K Key, V any] struct {
rm sync.RWMutex
entry map[K]V
}
func NewChild[K Key, V any]() *Child[K, V] {
return &Child[K, V]{
entry: make(map[K]V),
}
}
// Add return old value
func (c *Child[K, V]) Add(key K, v V) V {
c.rm.Lock()
defer c.rm.Unlock()
var old V
p, ok := c.entry[key]
if !ok {
c.entry[key] = v
} else {
old = p
p = v
}
return old
}
func (c *Child[K, V]) Get(key K) (V, bool) {
c.rm.RLock()
defer c.rm.RUnlock()
p, ok := c.entry[key]
if ok {
return p, true
}
var ret V
return ret, false
}
func (c *Child[K, V]) Remove(key K) (V, bool) {
c.rm.Lock()
defer c.rm.Unlock()
p, ok := c.entry[key]
if ok {
delete(c.entry, key)
return p, true
}
var ret V
return ret, false
}
func (c *Child[K, V]) Delete(where func(v V) bool) {
c.rm.Lock()
defer c.rm.Unlock()
var keys []K
for k, v := range c.entry {
if where(v) {
keys = append(keys, k)
}
}
for _, key := range keys {
delete(c.entry, key)
}
}
func (c *Child[K, V]) Values(where func(k K, v V) bool) []V {
c.rm.RLock()
defer c.rm.RUnlock()
var values []V
for k, v := range c.entry {
if where(k, v) {
values = append(values, v)
}
}
return values
}
func (c *Child[K, V]) Foreach(each func(key K, c V)) {
c.rm.RLock()
defer c.rm.RUnlock()
for k, v := range c.entry {
each(k, v)
}
}
type Part[O any, K Key, V any] struct {
obj O
child *Child[K, V]
}
func (c *Part[O, K, V]) Get() O {
return c.obj
}
func (c *Part[O, K, V]) Set(v O) {
c.obj = v
}
// AddChild return old value
func (c *Part[O, K, V]) AddChild(key K, v V) V {
return c.child.Add(key, v)
}
func (c *Part[O, K, V]) GetChild(key K) (V, bool) {
return c.child.Get(key)
}
func (c *Part[O, K, V]) RemoveChild(key K) (V, bool) {
return c.child.Remove(key)
}
func (c *Part[O, K, V]) DeleteChild(where func(v V) bool) {
c.child.Delete(where)
}
func (c *Part[O, K, V]) ChildList(where func(k K, v V) bool) []V {
return c.child.Values(where)
}
func (c *Part[O, K, V]) ForeachChild(each func(key K, c V)) {
c.child.Foreach(each)
}
type Cache[M Key, O any, K Key, V any] struct {
useChild bool
rm sync.RWMutex
objs map[M]*Part[O, K, V]
}
func New[M Key, O any, K Key, V any](useChild bool) *Cache[M, O, K, V] {
return &Cache[M, O, K, V]{
useChild: useChild,
objs: make(map[M]*Part[O, K, V]),
}
}
func (c *Cache[M, O, K, V]) Add(key M, v O) *Part[O, K, V] {
c.rm.Lock()
defer c.rm.Unlock()
p, ok := c.objs[key]
if !ok {
var child *Child[K, V]
if c.useChild {
child = NewChild[K, V]()
}
p = &Part[O, K, V]{
obj: v,
child: child,
}
c.objs[key] = p
} else {
p.obj = v
}
return p
}
func (c *Cache[M, O, K, V]) Get(key M) *Part[O, K, V] {
c.rm.RLock()
defer c.rm.RUnlock()
p, ok := c.objs[key]
if ok {
return p
}
return nil
}
func (c *Cache[M, O, K, V]) Remove(key M) *Part[O, K, V] {
c.rm.Lock()
defer c.rm.Unlock()
p, ok := c.objs[key]
if ok {
delete(c.objs, key)
return p
}
return nil
}
func (c *Cache[M, O, K, V]) Delete(where func(key M, c *Part[O, K, V]) bool) {
c.rm.Lock()
defer c.rm.Unlock()
var keys []M
for k, v := range c.objs {
if where(k, v) {
keys = append(keys, k)
}
}
for _, key := range keys {
delete(c.objs, key)
}
}
func (c *Cache[M, O, K, V]) Child(key M, child K) (O, V, bool) {
part := c.Get(key)
if part == nil {
var o O
var ret V
return o, ret, false
}
ret, ok := part.GetChild(child)
return part.Get(), ret, ok
}
func (c *Cache[M, O, K, V]) ChildValues(key M, where func(k K, v V) bool) (O, []V, bool) {
part := c.Get(key)
if part == nil {
var o O
var ret []V
return o, ret, false
}
return part.Get(), part.ChildList(where), true
}
func (c *Cache[M, O, K, V]) Foreach(each func(key M, c *Part[O, K, V])) {
c.rm.RLock()
defer c.rm.RUnlock()
for k, v := range c.objs {
each(k, v)
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/h79/goutils.git
git@gitee.com:h79/goutils.git
h79
goutils
goutils
v1.21.3

搜索帮助