makeRoom deletes about 1/10 of the items in the cache in order to keep its size under control. It must not be called without a lock on c.mu.
()
| 231 | // in order to keep its size under control. It must not be |
| 232 | // called without a lock on c.mu. |
| 233 | func (c *Cache) makeRoom() { |
| 234 | // we delete more than just 1 entry so that we don't have |
| 235 | // to do this on every request; assuming the capacity of |
| 236 | // the cache is on a long tail, we can save a lot of CPU |
| 237 | // time by doing a whole bunch of deletions now and then |
| 238 | // we won't have to do them again for a while |
| 239 | numToDelete := max(len(c.cache)/10, 1) |
| 240 | for deleted := 0; deleted <= numToDelete; deleted++ { |
| 241 | // Go maps are "nondeterministic" not actually random, |
| 242 | // so although we could just chop off the "front" of the |
| 243 | // map with less code, this is a heavily skewed eviction |
| 244 | // strategy; generating random numbers is cheap and |
| 245 | // ensures a much better distribution. |
| 246 | //nolint:gosec |
| 247 | rnd := weakrand.IntN(len(c.cache)) |
| 248 | i := 0 |
| 249 | for key := range c.cache { |
| 250 | if i == rnd { |
| 251 | delete(c.cache, key) |
| 252 | break |
| 253 | } |
| 254 | i++ |
| 255 | } |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | // Comparer is a type that can securely compare |
| 260 | // a plaintext password with a hashed password |