github.com/saintwish/kv@v1.0.4/kv1s/kv1s.go (about) 1 package kv1s 2 3 import ( 4 "fmt" 5 6 "github.com/dolthub/maphash" 7 ) 8 9 type Cache[K comparable, V any] struct { 10 shards []shard[K, V] 11 shardCount uint64 12 hash maphash.Hasher[K] 13 14 OnDeleted 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("kv1s: shard count must be smaller than cache size!") 20 } 21 22 cache := Cache[K, V] {} 23 cache.shards = make([]shard[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] = newShard[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) shard[K, V] { 41 sum := c.hash.Hash(key) 42 return c.shards[sum%c.shardCount] 43 } 44 45 func (c *Cache[K, V]) SetOnDeleted(f func(K, V)) { 46 c.OnDeleted = 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]) GetHas(key K) (V, bool) { 55 shard := c.getShard(key) 56 return shard.getHas(key) 57 } 58 59 func (c *Cache[K, V]) Has(key K) bool { 60 shard := c.getShard(key) 61 return shard.has(key) 62 } 63 64 // Sets the key with value, will overwrite if key exists 65 func (c *Cache[K, V]) Set(key K, val V) { 66 shard := c.getShard(key) 67 shard.set(key, val) 68 } 69 70 // Adds key with value to map, will error if key already exists. 71 func (c *Cache[K, V]) Add(key K, val V) error { 72 shard := c.getShard(key) 73 if shard.has(key) { 74 return fmt.Errorf("kv1s: Data already exists with given key %T", key) 75 } 76 77 shard.set(key, val) 78 return nil 79 } 80 81 // Updates given key, errors if key doesn't already exists. 82 func (c *Cache[K, V]) Update(key K, val V) error { 83 shard := c.getShard(key) 84 if !shard.has(key) { 85 return fmt.Errorf("kv1s: Data doesn't exists with given key %T", key) 86 } 87 88 shard.update(key, val) 89 return nil 90 } 91 92 // Will Set or Update said key depending if exists or not. 93 func (c *Cache[K, V]) SetOrUpdate(key K, val V) { 94 shard := c.getShard(key) 95 if shard.has(key) { 96 shard.update(key, val) 97 }else{ 98 shard.set(key, val) 99 } 100 } 101 102 // Deletes key and returns boolean if sucessful. 103 func (c *Cache[K, V]) Delete(key K) bool { 104 shard := c.getShard(key) 105 return shard.delete(key) 106 } 107 108 // Deletes key and returns boolean if sucessful OnDeleted callback. 109 func (c *Cache[K, V]) DeleteCallback(key K) bool { 110 shard := c.getShard(key) 111 return shard.deleteCallback(key, c.OnDeleted) 112 } 113 114 func (c *Cache[K, V]) ShardCount() uint64 { 115 return c.shardCount 116 } 117 118 func (c *Cache[K, V]) GetShardSize(key K) int { 119 shard := c.getShard(key) 120 return shard.Map.Count() 121 } 122 123 func (c *Cache[K, V]) GetShardMaxSize(key K) int { 124 shard := c.getShard(key) 125 return shard.Map.MaxCapacity() 126 } 127 128 func (c *Cache[K, V]) GetShardCapacity(key K) int { 129 shard := c.getShard(key) 130 return shard.Map.Capacity() 131 } 132 133 // Gets the current amount of elements in the cache. 134 func (c *Cache[K, V]) Count() (count int) { 135 for i := 0; i < len(c.shards); i++ { 136 shard := c.shards[i] 137 count = count + shard.Map.Count() 138 } 139 return 140 } 141 142 // Clears the cache with OnEviction callback. 143 func (c *Cache[K, V]) Flush() { 144 for i := 0; i < len(c.shards); i++ { 145 shard := c.shards[i] 146 shard.flush(c.OnDeleted) 147 } 148 } 149 150 func (c *Cache[K, V]) Clear() { 151 for i := 0; i < len(c.shards); i++ { 152 shard := c.shards[i] 153 shard.clear() 154 } 155 } 156 157 func (c *Cache[K, V]) ForEach(f func(key K, val V)) { 158 for i := 0; i < len(c.shards); i++ { 159 shard := c.shards[i] 160 shard.Lock() 161 162 shard.Map.Iter(func(key K, val V) (stop bool) { 163 f(key, val) 164 165 if stop { 166 shard.Unlock() 167 return 168 } 169 170 return 171 }) 172 173 shard.Unlock() 174 } 175 }