| 221 | } |
| 222 | |
| 223 | func (c *FifoCache) put(key string, value []byte) { |
| 224 | // See if we already have the item in the cache. |
| 225 | element, ok := c.entries[key] |
| 226 | if ok { |
| 227 | // Remove the item from the cache. |
| 228 | entry := c.lru.Remove(element).(*cacheEntry) |
| 229 | delete(c.entries, key) |
| 230 | c.currSizeBytes -= sizeOf(entry) |
| 231 | c.entriesCurrent.Dec() |
| 232 | } |
| 233 | |
| 234 | entry := &cacheEntry{ |
| 235 | updated: time.Now(), |
| 236 | key: key, |
| 237 | value: value, |
| 238 | } |
| 239 | entrySz := sizeOf(entry) |
| 240 | |
| 241 | if c.maxSizeBytes > 0 && entrySz > c.maxSizeBytes { |
| 242 | // Cannot keep this item in the cache. |
| 243 | if ok { |
| 244 | // We do not replace this item. |
| 245 | c.entriesEvicted.Inc() |
| 246 | } |
| 247 | c.memoryBytes.Set(float64(c.currSizeBytes)) |
| 248 | return |
| 249 | } |
| 250 | |
| 251 | // Otherwise, see if we need to evict item(s). |
| 252 | for (c.maxSizeBytes > 0 && c.currSizeBytes+entrySz > c.maxSizeBytes) || (c.maxSizeItems > 0 && len(c.entries) >= c.maxSizeItems) { |
| 253 | lastElement := c.lru.Back() |
| 254 | if lastElement == nil { |
| 255 | break |
| 256 | } |
| 257 | evicted := c.lru.Remove(lastElement).(*cacheEntry) |
| 258 | delete(c.entries, evicted.key) |
| 259 | c.currSizeBytes -= sizeOf(evicted) |
| 260 | c.entriesCurrent.Dec() |
| 261 | c.entriesEvicted.Inc() |
| 262 | } |
| 263 | |
| 264 | // Finally, we have space to add the item. |
| 265 | c.entries[key] = c.lru.PushFront(entry) |
| 266 | c.currSizeBytes += entrySz |
| 267 | if !ok { |
| 268 | c.entriesAddedNew.Inc() |
| 269 | } |
| 270 | c.entriesCurrent.Inc() |
| 271 | c.memoryBytes.Set(float64(c.currSizeBytes)) |
| 272 | } |
| 273 | |
| 274 | // Get returns the stored value against the key and when the key was last updated. |
| 275 | func (c *FifoCache) Get(ctx context.Context, key string) ([]byte, bool) { |