github.com/saintwish/kv@v1.0.4/kv2/kv2.go (about)

     1  package kv2
     2  
     3  import (
     4  	"fmt"
     5  	
     6  	"github.com/dolthub/maphash"
     7  )
     8  
     9  type Cache[K comparable, V any] struct {
    10  	shards []shardCapacity[K, V]
    11  	shardCount uint64
    12  	hash maphash.Hasher[K]
    13  
    14  	OnEvicted func(K, V) //function that's called when cached item is deleted by the system
    15  }
    16  
    17  func New[K comparable, V any](sz uint64, sc uint64) *Cache[K, V] {
    18  	if sc > sz {
    19  		panic("kv2: shard count must be smaller than cache size!")
    20  	}
    21  
    22  	cache := Cache[K, V] {}
    23  	cache.shards = make([]shardCapacity[K, V], sc)
    24  	cache.hash = maphash.NewHasher[K]()
    25  	cache.shardCount = sc
    26  
    27  	for i := 0; i < int(sc); i++ {
    28  		cache.shards[i] = newShardCapacity[K, V](sz, sc)
    29  	}
    30  
    31  	return &cache
    32  }
    33  
    34  func (c *Cache[K, V]) getShardIndex(key K) uint64 {
    35  	sum := c.hash.Hash(key)
    36  
    37  	return sum % c.shardCount
    38  }
    39  
    40  func (c *Cache[K, V]) getShard(key K) shardCapacity[K, V] {
    41  	sum := c.hash.Hash(key)
    42  	return c.shards[sum%c.shardCount]
    43  }
    44  
    45  func (c *Cache[K, V]) SetOnEvicted(f func(K, V)) {
    46  	c.OnEvicted = f
    47  }
    48  
    49  func (c *Cache[K, V]) Get(key K) V {
    50  	shard := c.getShard(key)
    51  	return shard.get(key)
    52  }
    53  
    54  func (c *Cache[K, V]) GetRenew(key K) V {
    55  	shard := c.getShard(key)
    56  	return shard.getRenew(key)
    57  }
    58  
    59  func (c *Cache[K, V]) GetHas(key K) (V, bool) {
    60  	shard := c.getShard(key)
    61  	return shard.getHas(key)
    62  }
    63  
    64  func (c *Cache[K, V]) GetHasRenew(key K) (V, bool) {
    65  	shard := c.getShard(key)
    66  	return shard.getHasRenew(key)
    67  }
    68  
    69  func (c *Cache[K, V]) Has(key K) bool {
    70  	shard := c.getShard(key)
    71  	return shard.has(key)
    72  }
    73  
    74  func (c *Cache[K, V]) Set(key K, val V) {
    75  	shard := c.getShard(key)
    76  	shard.set(key, val, c.OnEvicted)
    77  }
    78  
    79  func (c *Cache[K, V]) Add(key K, val V) error {
    80  	shard := c.getShard(key)
    81  	if shard.has(key) {
    82  		return fmt.Errorf("kv2: Data already exists with given key %T", key)
    83  	}
    84  
    85  	shard.set(key, val, c.OnEvicted)
    86  	return nil
    87  }
    88  
    89  func (c *Cache[K, V]) Update(key K, val V) error {
    90  	shard := c.getShard(key)
    91  	if !shard.has(key) {
    92  		return fmt.Errorf("kv2: Data doesn't exists with given key %T", key)
    93  	}
    94  
    95  	shard.update(key, val)
    96  	return nil
    97  }
    98  
    99  func (c *Cache[K, V]) SetOrUpdate(key K, val V) {
   100  	shard := c.getShard(key)
   101  	if shard.has(key) {
   102  		shard.update(key, val)
   103  	}else{
   104  		shard.set(key, val, c.OnEvicted)
   105  	}
   106  }
   107  
   108  func (c *Cache[K, V]) Delete(key K) bool {
   109  	shard := c.getShard(key)
   110  	return shard.delete(key)
   111  }
   112  
   113  func (c *Cache[K, V]) DeleteCallback(key K) bool {
   114  	shard := c.getShard(key)
   115  	return shard.deleteCallback(key, c.OnEvicted)
   116  }
   117  
   118  func (c *Cache[K, V]) ShardCount() uint64 {
   119  	return c.shardCount
   120  }
   121  
   122  func (c *Cache[K, V]) GetShardSize(key K) int {
   123  	shard := c.getShard(key)
   124  	return shard.Map.Count()
   125  }
   126  
   127  func (c *Cache[K, V]) GetShardMaxSize(key K) int {
   128  	shard := c.getShard(key)
   129  	return shard.Map.MaxCapacity()
   130  }
   131  
   132  func (c *Cache[K, V]) GetShardCapacity(key K) int {
   133  	shard := c.getShard(key)
   134  	return shard.Map.Capacity()
   135  }
   136  
   137  // Clears the cache with calling OnEviction callback
   138  func (c *Cache[K, V]) Flush() {
   139  	for i := 0; i < len(c.shards); i++ {
   140  		shard := c.shards[i]
   141  		shard.flush(c.OnEvicted)
   142  	}
   143  }
   144  
   145  // Clears the cache without calling OnEviction callback
   146  func (c *Cache[K, V]) Clear() {
   147  	for i := 0; i < len(c.shards); i++ {
   148  		shard := c.shards[i]
   149  		shard.clear()
   150  	}
   151  }
   152  
   153  func (c *Cache[K, V]) ForEach(f func(key K, val V)) {
   154  	for i := 0; i < len(c.shards); i++ {
   155  		shard := c.shards[i]
   156  		shard.Lock()
   157  
   158  		shard.Map.Iter(func(key K, val item[V]) (stop bool) {
   159  			f(key, val.Object)
   160  
   161  			if stop {
   162  				shard.Unlock()
   163  				return
   164  			}
   165  
   166  			return
   167  		})
   168  
   169  		shard.Unlock()
   170  	}
   171  }