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