gitee.com/h79/goutils@v1.22.10/common/cache/cache.go (about)

     1  package cache
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  type Key interface {
     8  	~int | ~int16 | ~int32 | ~int64 | ~uint32 | uint16 | ~uint | ~string
     9  }
    10  
    11  type Child[K Key, V any] struct {
    12  	rm    sync.RWMutex
    13  	entry map[K]V
    14  }
    15  
    16  func NewChild[K Key, V any]() *Child[K, V] {
    17  	return &Child[K, V]{
    18  		entry: make(map[K]V),
    19  	}
    20  }
    21  
    22  // Add return old value
    23  func (c *Child[K, V]) Add(key K, v V, force bool) (cur V, old V) {
    24  	c.rm.Lock()
    25  	defer c.rm.Unlock()
    26  	p, ok := c.entry[key]
    27  	if !ok {
    28  		c.entry[key] = v
    29  		return v, old
    30  	}
    31  	if force {
    32  		old = p
    33  		c.entry[key] = v
    34  		return v, old
    35  	}
    36  	return p, old
    37  }
    38  
    39  func (c *Child[K, V]) Get(key K) (V, bool) {
    40  	c.rm.RLock()
    41  	defer c.rm.RUnlock()
    42  	p, ok := c.entry[key]
    43  	if ok {
    44  		return p, true
    45  	}
    46  	var ret V
    47  	return ret, false
    48  }
    49  
    50  func (c *Child[K, V]) Remove(key K) (V, bool) {
    51  	c.rm.Lock()
    52  	defer c.rm.Unlock()
    53  	p, ok := c.entry[key]
    54  	if ok {
    55  		delete(c.entry, key)
    56  		return p, true
    57  	}
    58  	var ret V
    59  	return ret, false
    60  }
    61  
    62  func (c *Child[K, V]) Delete(where func(v V) bool) {
    63  	c.rm.Lock()
    64  	defer c.rm.Unlock()
    65  	var keys []K
    66  	for k, v := range c.entry {
    67  		if where(v) {
    68  			keys = append(keys, k)
    69  		}
    70  	}
    71  	for _, key := range keys {
    72  		delete(c.entry, key)
    73  	}
    74  }
    75  
    76  func (c *Child[K, V]) Values(where func(k K, v V) bool) []V {
    77  	c.rm.RLock()
    78  	defer c.rm.RUnlock()
    79  	var values []V
    80  	for k, v := range c.entry {
    81  		if where(k, v) {
    82  			values = append(values, v)
    83  		}
    84  	}
    85  	return values
    86  }
    87  
    88  func (c *Child[K, V]) Foreach(each func(key K, c V)) {
    89  	c.rm.RLock()
    90  	defer c.rm.RUnlock()
    91  	for k, v := range c.entry {
    92  		each(k, v)
    93  	}
    94  }
    95  
    96  type Part[O any, K Key, V any] struct {
    97  	obj   O
    98  	child *Child[K, V]
    99  }
   100  
   101  func (c *Part[O, K, V]) Get() O {
   102  	return c.obj
   103  }
   104  
   105  func (c *Part[O, K, V]) Set(v O) {
   106  	c.obj = v
   107  }
   108  
   109  // AddChild return old value
   110  func (c *Part[O, K, V]) AddChild(key K, v V, force bool) (cur V, old V) {
   111  	return c.child.Add(key, v, force)
   112  }
   113  
   114  func (c *Part[O, K, V]) GetChild(key K) (V, bool) {
   115  	return c.child.Get(key)
   116  }
   117  
   118  func (c *Part[O, K, V]) RemoveChild(key K) (V, bool) {
   119  	return c.child.Remove(key)
   120  }
   121  
   122  func (c *Part[O, K, V]) DeleteChild(where func(v V) bool) {
   123  	c.child.Delete(where)
   124  }
   125  
   126  func (c *Part[O, K, V]) ChildList(where func(k K, v V) bool) []V {
   127  	return c.child.Values(where)
   128  }
   129  
   130  func (c *Part[O, K, V]) ForeachChild(each func(key K, c V)) {
   131  	c.child.Foreach(each)
   132  }
   133  
   134  type Cache[M Key, O any, K Key, V any] struct {
   135  	useChild bool
   136  	rm       sync.RWMutex
   137  	objs     map[M]*Part[O, K, V]
   138  }
   139  
   140  func New[M Key, O any, K Key, V any](useChild bool) *Cache[M, O, K, V] {
   141  	return &Cache[M, O, K, V]{
   142  		useChild: useChild,
   143  		objs:     make(map[M]*Part[O, K, V]),
   144  	}
   145  }
   146  
   147  func (c *Cache[M, O, K, V]) Add(key M, o O, force bool) (part *Part[O, K, V], cur O, old O) {
   148  	c.rm.Lock()
   149  	defer c.rm.Unlock()
   150  	part, ok := c.objs[key]
   151  	if !ok {
   152  		var child *Child[K, V]
   153  		if c.useChild {
   154  			child = NewChild[K, V]()
   155  		}
   156  		part = &Part[O, K, V]{
   157  			obj:   o,
   158  			child: child,
   159  		}
   160  		c.objs[key] = part
   161  		return part, o, old
   162  	}
   163  	if force {
   164  		old = part.obj
   165  		part.obj = o
   166  		return part, o, old
   167  	}
   168  	return part, part.obj, old
   169  }
   170  
   171  func (c *Cache[M, O, K, V]) Get(key M) *Part[O, K, V] {
   172  	c.rm.RLock()
   173  	defer c.rm.RUnlock()
   174  	p, ok := c.objs[key]
   175  	if ok {
   176  		return p
   177  	}
   178  	return nil
   179  }
   180  
   181  func (c *Cache[M, O, K, V]) Remove(key M) *Part[O, K, V] {
   182  	c.rm.Lock()
   183  	defer c.rm.Unlock()
   184  	p, ok := c.objs[key]
   185  	if ok {
   186  		delete(c.objs, key)
   187  		return p
   188  	}
   189  	return nil
   190  }
   191  
   192  func (c *Cache[M, O, K, V]) Delete(where func(key M, c *Part[O, K, V]) bool) {
   193  	c.rm.Lock()
   194  	defer c.rm.Unlock()
   195  	var keys []M
   196  	for k, v := range c.objs {
   197  		if where(k, v) {
   198  			keys = append(keys, k)
   199  		}
   200  	}
   201  	for _, key := range keys {
   202  		delete(c.objs, key)
   203  	}
   204  }
   205  
   206  func (c *Cache[M, O, K, V]) Child(key M, child K) (O, V, bool) {
   207  	part := c.Get(key)
   208  	if part == nil {
   209  		var o O
   210  		var ret V
   211  		return o, ret, false
   212  	}
   213  	ret, ok := part.GetChild(child)
   214  	return part.Get(), ret, ok
   215  }
   216  
   217  func (c *Cache[M, O, K, V]) ChildValues(key M, where func(k K, v V) bool) (O, []V, bool) {
   218  	part := c.Get(key)
   219  	if part == nil {
   220  		var o O
   221  		var ret []V
   222  		return o, ret, false
   223  	}
   224  	return part.Get(), part.ChildList(where), true
   225  }
   226  
   227  func (c *Cache[M, O, K, V]) Foreach(each func(key M, c *Part[O, K, V])) {
   228  	c.rm.RLock()
   229  	defer c.rm.RUnlock()
   230  	for k, v := range c.objs {
   231  		each(k, v)
   232  	}
   233  }