github.com/saintwish/kv@v1.0.4/kv1/shard.go (about) 1 package kv1 2 3 import ( 4 "time" 5 "sync" 6 7 "github.com/saintwish/kv/swiss" 8 ) 9 10 type item[V any] struct { 11 Object V 12 Expire time.Time 13 } 14 15 //used internally 16 type shard[K comparable, V any] struct { 17 Map *swiss.Map[K, item[V]] 18 Expiration time.Duration 19 *sync.RWMutex //mutex 20 } 21 22 func newShard[K comparable, V any](ex time.Duration, size uint64, count uint64) shard[K, V] { 23 return shard[K, V] { 24 Map: swiss.NewMap[K, item[V]]( uint32(size/count) ), 25 Expiration: ex, 26 RWMutex: &sync.RWMutex{}, 27 } 28 } 29 30 /*-------- 31 Raw get functions. 32 ----------*/ 33 func (m shard[K, V]) get(key K) (val V) { 34 m.RLock() 35 36 val = m.Map.Get(key).Object 37 38 m.RUnlock() 39 40 return 41 } 42 43 func (m shard[K, V]) getRenew(key K) (val V) { 44 m.Lock() 45 46 if ok,v := m.Map.GetHas(key); ok { 47 v.Expire = time.Now().Add(m.Expiration) 48 m.Map.Set(key, v) 49 val = v.Object 50 } 51 52 m.Unlock() 53 54 return 55 } 56 57 func (m shard[K, V]) has(key K) (ok bool) { 58 m.RLock() 59 60 ok = m.Map.Has(key) 61 62 m.RUnlock() 63 64 return 65 } 66 67 func (m shard[K, V]) getHas(key K) (val V, ok bool) { 68 m.RLock() 69 70 ok,v := m.Map.GetHas(key); 71 val = v.Object 72 73 m.RUnlock() 74 75 return 76 } 77 78 func (m shard[K, V]) getHasRenew(key K) (val V, ok bool) { 79 m.Lock() 80 81 if ok,v := m.Map.GetHas(key); ok { 82 v.Expire = time.Now().Add(m.Expiration) 83 m.Map.Set(key, v) 84 val = v.Object 85 } 86 87 m.Unlock() 88 89 return 90 } 91 92 93 /*-------- 94 Other functions 95 ----------*/ 96 func (m shard[K, V]) set(key K, val V) { 97 itm := item[V]{ 98 Object: val, 99 Expire: time.Now().Add(m.Expiration), 100 } 101 102 m.Lock() 103 104 m.Map.Set(key, itm) 105 106 m.Unlock() 107 } 108 109 func (m shard[K, V]) update(key K, val V) { 110 itm := item[V]{ 111 Object: val, 112 Expire: time.Now().Add(m.Expiration), 113 } 114 115 m.Lock() 116 117 if ok := m.Map.Has(key); ok { 118 m.Map.Set(key, itm) 119 } 120 121 m.Unlock() 122 } 123 124 func (m shard[K, V]) delete(key K) (ok bool) { 125 m.Lock() 126 127 ok, _ = m.Map.Delete(key) 128 129 m.Unlock() 130 131 return 132 } 133 134 func (m shard[K, V]) isExpired(key K) (ex bool) { 135 m.RLock() 136 137 if ok,v:= m.Map.GetHas(key); ok { 138 ex = time.Now().After(v.Expire) 139 } 140 141 m.RUnlock() 142 return 143 } 144 145 //Returns true if item is expired and thus evicted. 146 func (m shard[K, V]) evictItem(key K, callback func(K,V)) (ex bool) { 147 m.Lock() 148 149 ex = false 150 if ok,v := m.Map.GetHas(key); ok { 151 if time.Now().After(v.Expire) { 152 ex = true 153 callback(key, v.Object) 154 m.Map.Delete(key) 155 } 156 } 157 158 m.Unlock() 159 160 return 161 } 162 163 func (m shard[K, V]) evictExpired(callback func(K,V)) { 164 m.Lock() 165 166 m.Map.Iter(func (key K, v item[V]) (stop bool) { 167 if time.Now().After(v.Expire) { 168 callback(key, v.Object) 169 m.Map.Delete(key) 170 } 171 172 if stop { 173 m.Unlock() 174 return 175 } 176 177 return 178 }) 179 180 m.Unlock() 181 } 182 183 func (m shard[K, V]) renew(key K) { 184 expire := time.Now().Add(m.Expiration) 185 186 m.Lock() 187 188 if ok,v := m.Map.GetHas(key); ok { 189 v.Expire = expire 190 } 191 192 m.Unlock() 193 } 194 195 func (m shard[K, V]) clear() { 196 m.Map.Clear() 197 } 198 199 func (m shard[K, V]) flush(callback func(K, V)) { 200 m.Lock() 201 202 m.Map.Iter(func(key K, val item[V]) (stop bool) { 203 callback(key, val.Object) 204 m.Map.Delete(key) 205 206 if stop { 207 m.Unlock() 208 return 209 } 210 211 return 212 }) 213 214 m.Unlock() 215 }